Почему sudo игнорирует псевдонимы?


22

Я использую Ubuntu 10.04 и использую его upstartдля управления демонами. Моё корпоративное приложение запускается как демон и должно запускаться как root из-за различных привилегий. Например:

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

Я хотел бы представить aliasаббревиатуру этих команд как что-то вроде:

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

и запустить его как startappи это работает, но я бы предпочел не иметь sudo в псевдониме.

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

не при запуске с помощью sudo startapp, возвращая sudo: startapp: command not found.

Однако, когда я добавил псевдоним:

alias sudo='sudo '

sudo startapp сейчас работает, но мне все еще интересно, почему sudo игнорирует псевдонимы.


Ты бежал source ~/.bashrc? Это обновляет файл .bashrc и делает новые псевдонимы доступными?
Мана

@manu Да, я сделал
амфибия

Ответы:


35

Я вижу ниже информацию отсюда .

При использовании sudo используйте расширение alias (иначе sudo игнорирует ваши псевдонимы)

alias sudo='sudo '

Причина, почему это не работает, объясняется здесь .

Bash проверяет только первое слово команды на наличие псевдонима, любые слова после этого не проверяются. Это означает, что в такой команде, как sudo ll, bash проверяет псевдоним только первое слово (sudo), ll игнорируется. Мы можем сказать bash проверить следующее слово после псевдонима (т.е. sudo), добавив пробел в конец значения псевдонима.


6

Псевдонимы и функции определены в оболочке. Sudo - это внешняя программа. Поэтому sudo не видит псевдонимы, функции или встроенные функции оболочки, только внешние команды.

Под псевдонимами подразумеваются альтернативные имена команд, поэтому оболочка раскрывает их только в позиции команды, а не в том случае, если они являются аргументами для команд. Zsh поддерживает глобальные псевдонимы, которые раскрываются в любом месте командной строки, и их лучше использовать экономно, так как существует риск их случайного расширения даже в тех случаях, когда псевдоним не имеет смысла.

Вы можете сказать Sudo для вызова оболочки: sudo sh -c '…shell command here…'. Однако ваши обычные псевдонимы не будут доступны внутри этой команды оболочки, поскольку они обычно хранятся в файле, таком как ~/.bashrcили ~/.zshrcкоторый читается только интерактивными оболочками.

alias sudo='sudo ', как предложил Рамеш , заставляет оболочку расширять псевдонимы после sudo.


1
Работает ли и alias sudo='sudo 'на ZSH?
CMCDragonkai

2
@CMCDragonkai Да
Жиль "

1

Решение для пользователей Zsh

И в bash, и в zsh завершение псевдонима пробелом заставит оболочку псевдонимом-раскрыть следующее слово. Это позволяет что-то вроде следующего, чтобы расширить псевдонимmyalias

alias 'sudo=sudo '
sudo myalias

К сожалению, это разваливается, когда у вас есть более одного слова в вашем псевдониме (например sudo -u someone. Однако вы можете использовать zsh «глобальные псевдонимы», чтобы вручную расширять псевдонимы в любой части команды.

alias -g '$= '

Это создает глобальный псевдоним, который называется $(вы можете использовать любое слово), который заканчивается пробелом. Это заставляет zsh развернуть следующее слово как псевдоним обычной команды. Поскольку псевдоним расширяется до пробела, он не будет рассматриваться как аргумент. Это позволяет следующему работать.

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

Вы даже можете использовать $несколько раз в одной командной строке, если у вас сложное командное вложение. Я нашел это достаточно полезным, так как он постоянно находится в моем zshrc, но псевдоним достаточно прост, чтобы определить, когда вам нужно его использовать.


0

Я просто дал альтернативный ответ здесь без переопределения sudoпсевдонимом.

В вашем случае это будет:

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

Все в одной строке, без дополнительных оболочек, без переопределения псевдонимов. ;-)


Ох, подожди минутку - я понял - ты используешь, xargsчтобы раздеть цитаты, и grep, чтобы раздеть ведущие =. Вроде умный, но, наверное, ненужный. eval "sudo $(alias aliasname | cut -d= -f2-)"скорее всего лучше - xargsне всегда будет правильно обрабатывать кавычки, и там может быть больше одного =.
mikeserv

@mikeserv Я сожалею, что вы не поняли ;-) xargsне читайте цитаты. Именно grep принимает разрешенную команду между кавычками. Вы знаете, type -a alias_nameвозвращает что-то вроде alias_name is aliased to command_within_quotes. Кстати, я попробовал вашу команду и не работал на моем Ubuntu :-(. Это возвращение type -aразных версий Linux (я сомневаюсь в этом).
love.by.Iesus

Я знаю, что typeделает - в bash. Вы понимаете, однако, что цитаты удвоены, верно? Вы пробовали это с псевдонимом, который содержал одинарные кавычки? Во всяком случае, вы правы моя вещь не работает - вам нужно либо eval "sudo sh -c "$(...или eval "'sudo $(alias alias_name| cut -d\' -f2-)". Дело в том, что aliasони в основном предварительно настроены eval- aliasутилита специально должна выводить их содержимое, чтобы его можно было безопасно переустановить в оболочку. Я думаю, что ваш xargsреализован, чтобы сгладить пробелы? Просто будь осторожен с этим, хорошо?
mikeserv
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.