Чому судо ігнорує псевдоніми?


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і це працює, але я вважаю за краще не мати судо на псевдонімі.

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

не під час запуску з використанням sudo startapp, повернення sudo: startapp: command not found.

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

alias sudo='sudo '

sudo startapp Зараз працює, але мені все ще цікаво, чому Судо ігнорує псевдоніми.


Ви бігали source ~/.bashrc? Це оновлює файл .bashrc і робить доступними нові псевдоніми?
ман

@manu Так, я
амфібій

Відповіді:


35

Я бачу цю інформацію, перш тут .

Під час використання sudo використовуйте розширення псевдоніму (інакше sudo ігнорує ваші псевдоніми)

alias sudo='sudo '

Причина, чому це не працює, пояснюється тут .

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


6

Псевдоніми та функції визначені в оболонці. Судо - це зовнішня програма. Тож sudo не бачить псевдоніми, функції чи вбудовані оболонки, лише зовнішні команди.

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

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

alias sudo='sudo ', запропонований Рамешем , змушує оболонку розширювати псевдоніми після sudo.


1
Чи alias sudo='sudo 'працює також для ЗШ?
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щоб зняти цитати, а греп - щоб зняти провідну =. Якийсь розумний, але, напевно, непотрібний. eval "sudo $(alias aliasname | cut -d= -f2-)"це, мабуть, краще - xargsне завжди буде правильно поводитися з цитатами, а там може бути більше одного =.
mikeserv

@mikeserv Вибачте, ви цього не отримали ;-) xargsне знімайте цитати. Це греп, який приймає розв'язану команду з-поміж лапок. Ви знаєте, type -a alias_nameповертає щось на кшталт alias_name is aliased to command_within_quotes. До речі , я спробував вашу команду і не працює на моєму Убунту :-( Це повернення. type -aРозрізнялися між версіями Linux (я сумніваюся) ?.
loved.by.Jesus

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