ชื่อแทนไม่สามารถใช้ได้เมื่อใช้ sudo


159

วันนี้ฉันเล่นกับนามแฝงและฉันสังเกตว่านามแฝงดูเหมือนจะไม่สามารถใช้ได้ในขณะที่ใช้sudo:

danny@kaon:~$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

danny@kaon:~$ ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //

danny@kaon:~$ sudo -i
root@kaon:~# ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //
root@kaon:~# exit
logout

danny@kaon:~$ sudo ll -d /
sudo: ll: command not found

มีเหตุผลใดบ้างที่คุณไม่สามารถใช้นามแฝงในขณะใช้งานได้sudo?


คุณได้ประกาศนามแฝงเหล่านั้นใน. bashrc on / root /
Luciano Facchinelli

2
@LucianoFacchinelli: /root/.bashrcไม่ได้รับการอ่านเมื่อใช้คำสั่งผ่าน sudo
Flimm


@Flimm: แล้วsudo -iไงล่ะ
Evi1M4chine

คำตอบ:


250

เพิ่มบรรทัดต่อไปนี้ใน~/.bashrc:

alias sudo='sudo '

จากคู่มือทุบตี :

นามแฝงอนุญาตให้ใช้สตริงแทนคำได้เมื่อใช้เป็นคำแรกของคำสั่งแบบง่าย เชลล์เก็บรักษารายการของนามแฝงที่อาจถูกตั้งค่าและยกเลิกการตั้งค่าด้วยคำสั่ง alias และ unalias builtin

คำแรกของแต่ละคำสั่งง่าย ๆ ถ้าไม่ได้อยู่ในเครื่องหมายคำพูดจะถูกตรวจสอบเพื่อดูว่ามันมีนามแฝงหรือไม่ ถ้าเป็นเช่นนั้นคำนั้นจะถูกแทนที่ด้วยข้อความของนามแฝง อักขระ '/', '$', '`', '=' และอักขระตัวพิมพ์ใหญ่ของเชลล์หรืออักขระที่อยู่ในรายการด้านบนอาจไม่ปรากฏในชื่อนามแฝง ข้อความการแทนที่อาจมีอินพุตเชลล์ที่ถูกต้องรวมถึงเชลล์เมตาอักขระ คำแรกของข้อความการแทนที่ถูกทดสอบสำหรับนามแฝง แต่คำที่เหมือนกันกับชื่อแทนที่กำลังขยายจะไม่ถูกขยายอีกเป็นครั้งที่สอง ซึ่งหมายความว่าอาจมีนามแฝงเป็น "ls -F" และ Bash ไม่พยายามขยายข้อความทดแทนซ้ำ ถ้าตัวอักษรตัวสุดท้ายของค่านามแฝงเป็นพื้นที่หรือแท็บตัวละครแล้วคำสั่งดังต่อไปนี้คำถัดนามแฝงนอกจากนี้ยังมีการตรวจสอบสำหรับการขยายตัวนามแฝง

(เน้นเหมือง)
Bash จะตรวจสอบคำแรกของคำสั่งเพื่อหานามแฝงเท่านั้นคำใด ๆ หลังจากนั้นจะไม่ถูกตรวจสอบ ซึ่งหมายความว่าในคำสั่งเช่นsudo llเดียวกับคำแรก ( sudo) จะถูกตรวจสอบโดยทุบตีสำหรับนามแฝงllจะถูกละเว้น เราสามารถบอกทุบตีเพื่อตรวจสอบคำถัดไปหลังจากนามแฝง (เช่นsudo) โดยการเพิ่มช่องว่างที่ส่วนท้ายของค่านามแฝง


18
ทางออกที่ดีงาม
ulidtko

ดังนั้นโดยพื้นฐานแล้วปัญหาที่เกิดขึ้นทำให้ความจริงที่ว่า sudo นั้นถูกตั้งโปรแกรมในลักษณะที่ไม่ได้ตรวจสอบนามแฝงดังนั้นจะไม่พบหรือไม่
kemra102

2
การอ่านเอกสารเห็นได้ชัดว่ามีประโยชน์มากมาย :-)
biocyberman

4
การพักนี้จะเกิดขึ้นไหมถ้าฉันใช้ธง sudo เช่นsudo -H ll?
Mark E. Haase

1
@mehaase ใช่ฉันพยายามแล้วมันก็หยุด
user31389

5

ฉันเขียนฟังก์ชัน Bash สำหรับเงาsudoนั้น

มันตรวจสอบว่าฉันมีนามแฝงสำหรับคำสั่งที่กำหนดและเรียกใช้คำสั่ง aliased แทนคำสั่งตัวอักษรsudoในกรณีนั้นหรือไม่

นี่คือหน้าที่ของฉันในฐานะหนึ่งซับ:

sudo() { if alias "$1" &> /dev/null ; then $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}" ; else command sudo $@ ; fi }

หรือจัดรูปแบบเป็นอย่างดี:

sudo() { 
    if alias "$1" &> /dev/null ; then 
        $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}"
    else 
        command sudo "$@"
    fi 
}

คุณสามารถผนวกเข้ากับ.bashrcไฟล์ของคุณอย่าลืมที่จะมาหรือรีสตาร์ทเครื่องเทอร์มินัลของคุณในภายหลังเพื่อใช้การเปลี่ยนแปลง


มันจะยอดเยี่ยมถ้ามันใช้ได้กับ sudo -H ll
uav

3

นามแฝงเป็นของผู้ใช้เฉพาะ - คุณจำเป็นต้องกำหนด /root/.bashrc


3
พวกเขาอยู่ภายใต้ /root/.bashrc แล้วนั่นไม่ใช่ปัญหา
kemra102

1
คำตอบนี้จะเป็นที่ถูกต้องสำหรับสถานการณ์เมื่อคุณใช้เปลือกของตัวเองเป็นหลักเช่นเดียวกับsudo -sหรือsudo -i(และเพียงถ้าทำงานด้วยตัวเองที่จะได้รับเปลือกรากไม่ได้ด้วยsudo -s command...หรือsudo -i command...รูปแบบ) หรือsudo bashหรือsudo suหรือสถานการณ์ที่คุณ คุณเปิดใช้งานการเข้าสู่ระบบรูทและมีรูทเชลล์ด้วยวิธีดังกล่าว เมื่อผู้ใช้ที่ไม่ใช่รูทเรียกใช้sudo command...จากเชลล์ของตนเองการขยายสมนามทำโดยเชลล์ที่ไม่ใช่รูทของตนเอง sudoไม่ขยายชื่อแทนดังนั้นเมื่อนำไปใช้กับสถานการณ์ที่อธิบายไว้ในคำถามคำตอบนี้ไม่ถูกต้อง
Eliah Kagan

3

@ อัลวินคำตอบคือคำตอบที่สั้นที่สุด ไม่ต้องสงสัยเลย! :-)

อย่างไรก็ตามผมคิดว่าวิธีการแก้ปัญหาบรรทัดคำสั่งที่จะรันคำสั่ง sudo aliased ในที่ไม่มีความจำเป็นที่จะกำหนดsudoที่มีaliasคำสั่ง

นี่คือข้อเสนอของฉันสำหรับผู้ที่มันอาจจะสนใจ:

วิธีการแก้

type -a <YOUR COMMAND HERE> | grep -o -P "(?<=\`).*(?=')" | xargs sudo

ตัวอย่าง

ในกรณีของllคำสั่ง

type -a ll | grep -o -P "(?<=\`).*(?=')" | xargs sudo

คำอธิบาย

เมื่อคุณมีนามแฝง (เช่น:) llคำสั่งtype -aจะส่งกลับนิพจน์ที่ใช้นามแฝง:

$type -a ll
ll is aliased to `ls -l'

เมื่อgrepคุณเลือกข้อความระหว่างเครื่องหมายเน้นเสียง `และเครื่องหมายวรรคตอน 'ในกรณีนั้นls -l

และxargsรันข้อความที่เลือกเป็นพารามิเตอร์ของls -lsudo

ใช่อีกเล็กน้อย แต่สะอาด ;-) ไม่จำเป็นต้องกำหนดsudoเป็นนามแฝง


3
อาจจะง่ายกว่านี้ถ้าคุณใช้aliasbuiltin เนื่องจากเอาต์พุตนั้นสะอาดกว่า เอาท์พุทalias ll alias ll='ls -ahlF'
muru

ต่อไปนี้เป็นรุ่นที่ผสมผสานข้อเสนอแนะของ @ alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudoMuru:
ACK_stoverflow

ฉันคิดว่าประเด็นของคำถามเดิมคือการบันทึกงานโดยไม่ต้องไปsudo -iก่อนเพื่อเรียกใช้คำสั่ง aliased แต่ทำทันที การมีคำสั่งที่ซับซ้อนเช่นนี้เอาชนะไปได้ คุณทำได้แค่อดีตและทำได้เร็วกว่ามาก
Evi1M4chine

1

ฉันมีวิธีแก้ปัญหาที่ดีอีกข้อหนึ่งซึ่งเพิ่มความไว้วางใจด้วย:

ใช้การทุบตีเสร็จสิ้นเพื่อแทนที่คำที่อยู่เบื้องหลังsudoด้วยชื่อแทนโดยอัตโนมัติเมื่อกดที่แท็บ

บันทึกสิ่งนี้เป็น/etc/bash_completion.d/sudo-alias.bashcompและควรโหลดโดยอัตโนมัติเมื่อเริ่มต้นเชลล์แบบโต้ตอบ:

_comp_sudo_alias() { from="$2"; COMPREPLY=()
  if [[ $COMP_CWORD == 1 ]]; then
    COMPREPLY=( "$( alias -p | grep "^ *alias $from=" | sed -r "s/^ *alias [^=]+='(.*)'$/\1/" )" )
    return 0
  fi
  return 1
}
complete -o bashdefault -o default -F _comp_sudo_alias sudo

จากนั้นลงชื่อเข้าใช้เทอร์มินัลใหม่และคุณน่าจะดี


มีวิธีการที่จะได้รับรายชื่อของนามแฝงโดยเฉพาะอย่างยิ่งความหมายสำหรับการเสร็จสิ้นเป็น:compgen -a
Muru

@muru: ขอบคุณ แต่ในกรณีนี้ฉันต้องการค่าไม่ใช่กุญแจ ดังนั้นนามแฝงที่ป้อนจะถูกแทนที่ด้วย คุณพิมพ์นามแฝง (เหมือนในsudo ll) กด [TAB ↹] และสคริปต์จะพบllในรายการของการมอบหมายนามแฝงตัดสิ่งที่มันได้รับมอบหมายและแทรกที่ (ดังนั้นคุณจะได้รับเช่นsudo ls -lahvF --color=auto --time-style=long-iso.)
Evi1M4chine

0

ฉันมีวิธีแก้ปัญหาที่แตกต่างกันโดยที่คุณไม่จำเป็นต้องเพิ่มsudoเป็นนามแฝง ฉันใช้ Linux Mint 17.3 แต่มันก็น่าจะคล้ายกับ Ubuntu

เมื่อคุณรูทแล้ว.profileจะทำการรันจากโฮมไดเร็กตอรี่ของมัน หากคุณไม่ทราบว่าโฮมไดเร็กทอรีภายใต้รูทคืออะไรคุณสามารถตรวจสอบกับ:

sudo su
echo $HOME

ที่คุณสามารถดูบ้านของเป็นroot /root/ตรวจสอบเนื้อหา:

cd $HOME
ls -al

ควรมี.profileไฟล์ เปิดไฟล์และเพิ่มบรรทัดต่อไปนี้:

if [ "$BASH" ]; then
    if [ -f ~/.bash_aliases];then
        . ~/.bash_aliases 
    fi
fi

.bash_aliasesโดยทั่วไปสิ่งที่ทุบตีสคริปต์นี้ไม่สามารถที่จะตรวจสอบไฟล์ที่เรียกว่า หากมีไฟล์อยู่ไฟล์จะเรียกใช้งานไฟล์

บันทึกไฟล์และสร้างนามแฝงของคุณ.profile .bash_aliasesหากคุณมีไฟล์นามแฝงอยู่แล้วให้คัดลอกไฟล์ไปยังตำแหน่งนี้

เปิดตัวเทอร์มินัลอีกครั้งและคุณก็พร้อมที่จะไป!


0

คำตอบที่ได้รับการโหวตสูงสุดเป็นคำตอบที่ยอดเยี่ยม อย่างไรก็ตามหากคุณพิมพ์sudo -iและยกระดับเป็นพรอมต์ sudo ( #) คุณจะไม่มีนามแฝงที่คุณต้องการใช้

ในการใช้ชื่อแทนของคุณ (และทุกอย่างอื่น) ที่#พร้อมท์ให้ใช้:

sudo cp "$PWD"/.bashrc /root/.bashrc

โดยที่ "$ PWD" ถูกขยายโดยอัตโนมัติเป็น "/ home / YOUR_USER_NAME"


0

@ WinEunuuchs2Unix: $PWDขยายไปยัง "ไดเรกทอรีทำงานปัจจุบัน" $HOMEฉันคิดว่าคุณต้องการ

นอกจากนี้สำหรับสถานการณ์ส่วนใหญ่อาจเป็นการดีที่สุดที่จะมีไฟล์. bashrc รูตแยกต่างหาก ในความเป็นจริงฉันจะทำให้มันเป็นไฟล์จริง/rootเชื่อมโยงไปยังมันในไดเรกทอรีบ้านของผู้ใช้ (เช่น.bashrc_root) และแหล่งที่มาจาก.bashrcไฟล์ของผู้ใช้ หากในภายหลังบัญชีผู้ใช้ที่มีสิทธิ์พิเศษนี้ไม่มีอยู่อีกต่อไป.bashrcไฟล์รูทยังคงมีให้สำหรับผู้ใช้รายอื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.