Tại sao sudo bỏ qua bí danh?


22

Tôi đang chạy Ubuntu 10.04 và tôi sử dụng upstartđể quản lý daemon. Ứng dụng doanh nghiệp của tôi được chạy dưới dạng daemon và phải được chạy dưới quyền root vì nhiều đặc quyền khác nhau. Ví dụ:

sudo start my-application-long-ID
sudo stop my-application-long-ID
etc

Tôi muốn giới thiệu một aliastừ viết tắt các lệnh này như sau:

alias startapp='sudo start my-application-long-ID'

và chạy nó như startappvà nó hoạt động nhưng tôi không muốn có sudo trong bí danh.

alias startapp='start my-application-long-ID'

không chạy khi sử dụng sudo startapp, trở về sudo: startapp: command not found.

Tuy nhiên, khi tôi thêm bí danh:

alias sudo='sudo '

sudo startapp Bây giờ hoạt động nhưng tôi vẫn tò mò tại sao sudo bỏ qua bí danh.


Bạn đã chạy source ~/.bashrcchưa? Điều này cập nhật tệp .bashrc và làm cho các bí danh mới có sẵn?
manu

@manu Vâng, tôi đã làm
lưỡng cư

Câu trả lời:


35

Tôi thấy các thông tin dưới đây từ đây .

Khi sử dụng sudo, hãy sử dụng mở rộng bí danh (nếu không sudo bỏ qua bí danh của bạn)

alias sudo='sudo '

Lý do tại sao nó không hoạt động được giải thích ở đây .

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, sẽ bị bỏ qua. Chúng ta có thể yêu cầu bash kiểm tra từ tiếp theo sau bí danh (ví dụ sudo) bằng cách thêm khoảng trắng vào cuối giá trị bí danh.


6

Bí danh và chức năng được xác định trong một vỏ. Sudo là một chương trình bên ngoài. Vì vậy, sudo không thấy bí danh, hàm hoặc hàm dựng sẵn, chỉ có các lệnh bên ngoài.

Bí danh có nghĩa là tên lệnh thay thế, vì vậy shell chỉ mở rộng chúng ở vị trí lệnh, không phải khi chúng là đối số của lệnh. Zsh hỗ trợ các bí danh toàn cầu, được mở rộng ở bất kỳ đâu trên dòng lệnh và sử dụng tốt nhất một cách tiết kiệm vì có nguy cơ vô tình mở rộng chúng ngay cả trong bối cảnh mà bí danh không có ý nghĩa.

Bạn có thể nói với sudo để gọi shell : sudo sh -c '…shell command here…'. Tuy nhiên, các bí danh thông thường của bạn sẽ không có sẵn trong lệnh shell đó, vì chúng thường được lưu trữ trong một tệp như ~/.bashrchoặc ~/.zshrcchỉ được đọc bởi các shell tương tác.

alias sudo='sudo ', như đề xuất của Ramesh , làm cho vỏ mở rộng bí danh sau sudo.


1
alias sudo='sudo 'hoạt động cho ZSH không?
CMCDragonkai


1

Một giải pháp cho người dùng zsh

Trong cả bash và zsh, việc kết thúc bí danh bằng dấu cách sẽ khiến shell trở thành bí danh - mở rộng từ tiếp theo. Điều này cho phép một cái gì đó như sau để mở rộng bí danhmyalias

alias 'sudo=sudo '
sudo myalias

Thật không may, điều này sụp đổ khi bạn có nhiều hơn một từ trong bí danh của mình (như sudo -u someone. Tuy nhiên, bạn có thể lạm dụng tính năng "bí danh toàn cầu" zsh để mở rộng bí danh ở bất kỳ đâu trong lệnh.

alias -g '$= '

Điều này tạo ra một bí danh toàn cầu được gọi là $(bạn có thể sử dụng bất kỳ từ nào bạn muốn) kết thúc trong một khoảng trắng. Điều này khiến zsh mở rộng từ tiếp theo dưới dạng bí danh lệnh thông thường. Vì bí danh mở rộng ra khoảng trắng, nó sẽ không được coi là một đối số. Điều này cho phép sau đây để làm việc.

% alias myalias=echo
% sudo -u someone myalias foo
sudo: myalias: command not found
% sudo -u someone $ myalias foo
foo

Bạn thậm chí có thể sử dụng $nhiều lần trên một dòng lệnh nếu bạn có lồng lệnh phức tạp. Tôi đã thấy điều này đủ hữu ích để nó có một vị trí cố định trong zshrc của tôi, tuy nhiên bí danh đủ đơn giản để xác định khi bạn cần sử dụng nó.


0

Tôi chỉ đưa ra một câu trả lời thay thế ở đây mà không cần xác định lại sudobằng bí danh.

Trong trường hợp của bạn, nó sẽ là:

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

Tất cả trong một dòng, không có vỏ bổ sung, không xác định lại bí danh. ;-)


Đợi một chút - tôi hiểu rồi - bạn đang sử dụng xargsđể trích dẫn các trích dẫn và grep để loại bỏ hàng đầu =. Kinda thông minh, nhưng có lẽ không cần thiết. eval "sudo $(alias aliasname | cut -d= -f2-)"có khả năng tốt hơn - xargssẽ không luôn luôn xử lý các trích dẫn một cách chính xác và có thể có nhiều hơn một =trong đó.
mikeerv

@mikeerv Tôi xin lỗi bạn đã không nhận được nó ;-) xargskhông loại bỏ các trích dẫn. Đó là grep người nhận lệnh được giải quyết từ giữa các dấu ngoặc kép. Bạn biết type -a alias_nametrả lại một cái gì đó như alias_name is aliased to command_within_quotes. Bằng cách này, tôi đã thử lệnh của bạn và không hoạt động trên Ubuntu của tôi :-(. Nó có phải là sự trở lại của type -acác phiên bản linux không? (Tôi nghi ngờ điều đó).
love.by.Jesus 16/215

Tôi biết những gì typekhông - trong bash. Bạn hiểu rằng, các trích dẫn được nhân đôi phải không? Bạn đã thử nó với một bí danh có chứa dấu ngoặc đơn chưa? Dù sao, bạn nói đúng về điều của tôi không hoạt động - bạn cần eval "sudo sh -c "$(...hoặc eval "'sudo $(alias alias_name| cut -d\' -f2-)". Vấn đề là aliasvề cơ bản được sắp xếp trước eval- aliastiện ích được chỉ định để xuất nội dung của chúng để nó có thể được khôi phục lại một cách an toàn cho trình bao. Tôi đoán của bạn xargsđược thực hiện sau đó để làm phẳng khoảng trắng? Chỉ cần cẩn thận với điều đó, ok?
mikeerv 16/2/2015
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.