Bí danh không có sẵn khi sử dụng sudo


161

Tôi đã chơi xung quanh với các bí danh ngày hôm nay và tôi nhận thấy rằng các bí danh dường như không có sẵn trong khi sử dụng 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

Có bất kỳ lý do tại sao bạn không thể sử dụng bí danh trong khi sử dụng sudo?


Bạn đã khai báo các bí danh đó trong .bashrc trên / root /
Luciano Facchinelli

2
@LucianoFacchinelli: /root/.bashrckhông được đọc khi chạy lệnh thông qua sudo.
Flimm


@Flimm: Thế còn sudo -i?
Evi1M4chine

Câu trả lời:


251

Thêm dòng sau vào ~/.bashrc:

alias sudo='sudo '

Từ hướng dẫn bash :

Bí danh cho phép một chuỗi được thay thế cho một từ khi nó được sử dụng làm từ đầu tiên của một lệnh đơn giản. Shell duy trì một danh sách các bí danh có thể được thiết lập và bỏ đặt với các lệnh dựng sẵn bí danh và unalias.

Từ đầu tiên của mỗi lệnh đơn giản, nếu không được trích dẫn, được kiểm tra xem nó có bí danh không . Nếu vậy, từ đó được thay thế bằng văn bản của bí danh. Các ký tự '/', '$', '`', '=' và bất kỳ ký tự đại diện hoặc ký tự trích dẫn nào được liệt kê ở trên có thể không xuất hiện trong tên bí danh. Văn bản thay thế có thể chứa bất kỳ đầu vào shell hợp lệ, bao gồm cả siêu ký tự shell. Từ đầu tiên của văn bản thay thế được kiểm tra các bí danh, nhưng một từ giống hệt với bí danh đang được mở rộng không được mở rộng lần thứ hai. Điều này có nghĩa là người ta có thể bí danh ls thành "ls -F", và Bash không cố gắng mở rộng đệ quy văn bản thay thế. Nếu ký tự cuối cùng của giá trị bí danh là ký tự khoảng trắng hoặc tab, thì từ lệnh tiếp theo sau bí danh cũng được kiểm tra để mở rộng bí danh .

(Nhấn mạnh mỏ).
Bash chỉ kiểm tra từ đầu tiên của một lệnh cho bí danh, bất kỳ từ nào sau đó không được kiểm tra. Điều đó có nghĩa là trong một lệnh như sudo ll, chỉ từ đầu tiên ( sudo) được kiểm tra bằng bash cho một bí danh, llbị bỏ qua. Chúng ta có thể yêu cầu bash kiểm tra từ tiếp theo sau bí danh (nghĩa là sudo) bằng cách thêm khoảng trắng vào cuối giá trị bí danh.


18
Giải pháp khá hay.
ulidtko

Vì vậy, về cơ bản vấn đề tập trung vào thực tế là sudo chỉ được lập trình theo cách mà nó không kiểm tra bí danh do đó sẽ không được tìm thấy?
kemra102

2
Đọc tài liệu rõ ràng có lợi rất nhiều :-)
biocyberman

4
Điều này sẽ phá vỡ nếu tôi sử dụng một cờ sudo, ví dụ sudo -H ll?
Đánh dấu E. Haase

1
@mehaase Vâng, tôi đã thử và nó bị hỏng.
dùng31389

5

Tôi đã viết một hàm Bash cho nó bóng sudo.

Nó kiểm tra xem tôi có bí danh cho lệnh đã cho hay không và chạy lệnh bí danh thay vì lệnh theo nghĩa đen sudotrong trường hợp đó.

Đây là chức năng của tôi như một lớp lót:

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

Hoặc được định dạng độc đáo:

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

Bạn có thể nối nó vào .bashrctệp của mình , đừng quên lấy nguồn hoặc khởi động lại phiên cuối của bạn sau đó để áp dụng các thay đổi.


Thật tuyệt vời nếu điều này cũng sẽ làm việc cho sudo -H ll.
uav

3

Các bí danh là người dùng cụ thể - bạn cần xác định chúng trong /root/.bashrc


3
Chúng đã ở dưới /root/.bashrc, vì vậy đó không phải là vấn đề
kemra102

1
Câu trả lời này sẽ chỉ đúng với tình huống khi bạn tự chạy shell với quyền root, như với sudo -shoặc sudo -i(và chỉ khi tự chạy để lấy shell root chứ không phải với sudo -s command...hoặc hoặc sudo -i command...biểu mẫu) sudo bashhoặc sudo su, hoặc tình huống nơi bạn Đã kích hoạt đăng nhập gốc và có vỏ gốc theo cách đó. Khi người dùng không phải root chạy sudo command...từ shell của chính họ, việc mở rộng bí danh được thực hiện bởi shell không phải root của họ. sudobản thân nó không mở rộng bí danh, vì vậy, áp dụng cho tình huống được mô tả trong câu hỏi , câu trả lời này không chính xác.
Eliah Kagan

3

Câu trả lời @Alvins là câu trả lời ngắn nhất. Không còn nghi ngờ gì nữa! :-)

Tuy nhiên tôi nghĩ đến một giải pháp dòng lệnh để thực thi một lệnh bí danh trong sudo khi không cần xác định lại sudobằng một aliaslệnh.

Đây là đề xuất của tôi cho những người mà nó có thể quan tâm:

Giải pháp

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

Thí dụ

Trong trường hợp của lllệnh

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

Giải trình

khi bạn có một bí danh (chẳng hạn như ll:), lệnh type -asẽ trả về biểu thức bí danh:

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

với grepbạn chọn văn bản giữa dấu 'và dấu nháy đơn' trong trường hợp đóls -l

xargsthực thi văn bản đã chọn ls -llàm tham số của sudo.

Có, lâu hơn một chút nhưng hoàn toàn sạch sẽ ;-) Không cần xác định lại sudolà bí danh.


3
Có thể đơn giản hơn nếu bạn sử dụng aliasnội dung, vì đầu ra của nó sạch hơn. alias llđầu ra alias ll='ls -ahlF'.
muru

Đây là phiên bản kết hợp đề xuất của @ muru : alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudo.
ACK_stoverflow

Tôi nghĩ rằng vấn đề của câu hỏi ban đầu là để tiết kiệm công việc bằng cách không phải sudo -itrước tiên, để chạy lệnh bí danh, nhưng thực hiện nó ngay lập tức. Có một lệnh phức tạp như vậy đánh bại điều đó. Bạn chỉ có thể làm trước đây, và nhanh hơn nhiều.
Evi1M4chine

1

Tôi có một giải pháp tốt khác, đó cũng là một chút tin tưởng:

Sử dụng hoàn thành bash để tự động thay thế các từ phía sau sudobằng bí danh của chúng khi nhấn tab.

Lưu cái này dưới dạng /etc/bash_completion.d/sudo-alias.bashcompvà nó sẽ tự động được tải khi khởi động shell tương tác:

_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

Sau đó đăng nhập vào một thiết bị đầu cuối mới, và bạn nên đi.


Có một cách để có được một danh sách các bí danh, đặc biệt có nghĩa là hoàn thành:compgen -a
muru

@muru: Cảm ơn, nhưng trong trường hợp này tôi cần các giá trị, không phải các khóa. Vì vậy, những gì bí danh đã được nhập sẽ được thay thế bằng. Bạn nhập bí danh, (như trong sudo ll), nhấn [TAB] và tập lệnh tìm thấy lltrong danh sách các bài tập bí danh, cắt bỏ những gì nó được gán cho nó và chèn nó. (Vì vậy, bạn sẽ nhận được ví dụ sudo ls -lahvF --color=auto --time-style=long-iso.)
Evi1M4chine

0

Tôi có một giải pháp khác theo đó bạn không cần thêm sudobí danh. Tôi chạy Linux Mint 17.3 nhưng nó khá giống với Ubuntu.

Khi bạn root, thì nó .profileđược chạy từ thư mục chính của nó. Nếu bạn không biết thư mục chính dưới gốc là gì, thì bạn có thể kiểm tra với:

sudo su
echo $HOME

Như bạn có thể thấy, nhà của root/root/. Kiểm tra nội dung của nó:

cd $HOME
ls -al

Cần có một .profiletập tin. Mở tệp và thêm các dòng sau:

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

Về cơ bản, những gì tập lệnh bash này làm là kiểm tra một tệp được gọi .bash_aliases. Nếu các tập tin có mặt, nó thực thi các tập tin.

Lưu .profiletệp và tạo bí danh của bạn trong .bash_aliases. Nếu bạn đã có sẵn tệp bí danh, thì sao chép tệp vào vị trí này

Khởi động lại thiết bị đầu cuối và bạn tốt để đi!


0

Câu trả lời được bình chọn hàng đầu là một câu trả lời tuyệt vời. Tuy nhiên, nếu bạn nhập sudo -ivà nâng lên một dấu nhắc sudo ( #) bạn sẽ không có bí danh bạn muốn sử dụng.

Để sử dụng bí danh của bạn (và mọi thứ khác) tại #dấu nhắc, hãy sử dụng:

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

Trong đó "$ PWD" được tự động mở rộng thành "/ home / YOU_USER_NAME"


0

@ WinEunuuchs2Unix: $PWDmở rộng đến "thư mục làm việc hiện tại". Tôi nghĩ bạn muốn$HOME .

Ngoài ra, trong hầu hết các tình huống, có lẽ tốt nhất là có một tệp .bashrc gốc. Trên thực tế, tôi sẽ biến nó thành một tệp thực sự /root, liên kết mềm đến nó trong thư mục chính của người dùng (ví dụ .bashrc_root:) và lấy nguồn từ .bashrctệp của người dùng . Nếu tại một thời điểm sau đó, tài khoản người dùng đặc quyền này không còn tồn tại, .bashrctệp gốc vẫn có sẵn cho những người dùng khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.