Как передать псевдоним через sudo

32

У меня есть псевдоним, который передает некоторые параметры инструменту, который я часто использую. Иногда я бегаю как сам, иногда под sudo. К сожалению, конечно, sudo не распознает псевдоним.

У кого-нибудь есть подсказка о том, как пропустить псевдоним?

В этом случае у меня есть куча вариантов для Perl, когда я отлаживаю:

alias pd='perl -Ilib -I/home/myuser/lib -d'

Иногда мне приходится отлаживать свои инструменты от имени пользователя root, поэтому вместо запуска:

pd ./mytool --some params

Мне нужно запустить его под sudo. Я пробовал много способов:

sudo eval $(alias pd)\; pd ./mytool --some params
sudo $(alias pd)\; pd ./mytool --some params
sudo bash -c "$(alias pd)\; pd ./mytool --some params"
sudo bash -c "$(alias pd); pd ./mytool --some params"
sudo bash -c eval\ "$(alias pd)\; pd ./mytool --some params"
sudo bash -c eval\ "'$(alias pd)\; pd ./mytool --some params'"

Я надеялся на хороший, краткий способ гарантировать, что мой текущий псевдоним pd был полностью использован (на случай, если мне понадобится настроить его позже), хотя некоторые из моих попыток не были краткими. Мое последнее средство - поместить его в сценарий оболочки и поместить в то место, которое sudo сможет найти. Но псевдонимы иногда очень удобны, так что это последнее средство.

Tanktalus
источник

Ответы:

50

Очень элегантное решение может быть найдено в Archlinux-Wiki:

alias sudo='sudo '
# whitespace ---^

работает, чтобы передать все псевдонимы sudo.

Источник: http://wiki.archlinux.org/index.php/Sudo#Passing_aliases

Slizzered
источник
16
Это отличный трюк! Для любопытных объяснение из раздела псевдонимов на man-странице bash:A trailing space in value causes the next word to be checked for alias substitution when the alias is expanded.
Рассел Дэвис,
1
Это действительно должен быть принятый ответ.
Адриан Фрувирт
Обидно, что это не работает для функций.
Сиро Сантилли 新疆 新疆 中心 法轮功 六四 事件
2
Заметка: Предположим , что вы действительно должны пройти опцию , чтобы sudoснова, в то время как желание сохранить этот sudo-passthrough трюк в то же время. Даже это можно сделать: чтобы снова использовать опции, используйте \sudo. Обратная косая черта переопределит псевдоним. (Многие, кажется, не знают об этом). Таким образом, вы можете ( опасность! ) Даже удалять файлы без какого-либо предупреждения, переопределяя alias rm='rm -i'обычно указанное в .bash-aliases, просто набирая \rm file-to-delete.
syntaxerror
11

Я не совсем понимаю, что вы пытаетесь сделать. Я вижу два пути:

Правильный путь

alias pd='sudo perl -Ilib -I/home/myuser/lib -d'

Затем выполнение pd ./mytoolвыполнит вашу команду отладки как root, но все равно сохранит преимущества sudo (контрольный журнал, не работающий из корневой оболочки).

Пример:

insyte $ alias sid = 'sudo id'
insyte $ sid
uid = 0 (root) gid = 0 (root) groups = 0 (root)

Легкий путь

Добавьте псевдонимы к root'ам .bashrcи используйте sudo -iвсякий раз, когда вы используете sudo для root.

root # echo 'alias fb = "echo foo bar"' >> /root/.bashrc
root # выход
выход
insyte $ sudo -i
root # fb
фу бар
Insyte
источник
4

Просто имейте два псевдонима и используйте переменную

Я не вижу причины для использования awk или cutразве только для того, чтобы псевдоним ядра был определен только один раз, чтобы его было легче модифицировать. Если это так, то это работает:

# ... in .bashrc ...
pd='perl -Ilib -I/home/myuser/lib -d'
alias pd="$pd"
alias spd="sudo $pd"

Вот упрощенная функция для создания пар псевдонимов, таких как приведенная выше:

mkap () {
    alias $1=$2
    alias s$1="sudo $2"
}

Использовать:

mkap pd 'perl -Ilib -I/home/myuser/lib -d'
mkap ct 'cat'

Теперь у вас есть pdи spdплюс ctи sct.

$ ct /etc/shadow
cat: /etc/shadow: Permission denied
$ sct /etc/shadow
[sudo] password for dennis:
root:[censored]...
$ alias
alias ct='cat'
alias pd='perl -Ilib -I/home/myuser/lib -d'
alias sct='sudo cat'
alias spd='sudo perl -Ilib -I/home/myuser/lib -d'
Приостановлено до дальнейшего уведомления.
источник
4

Хотел бы я отметить два ответа как «правильные». Комбинируя правильный путь из проницательного поста Insyte , с решением awk (или cut) от Билла Вайса , я придумал это:

alias spd="sudo $(alias pd | cut -d\' -f2)"

Теперь я просто пойду и вставлю это в функцию оболочки в моем .bashrc или что-то в этом роде, а затем создаю «s» версии всех моих псевдонимов, которые я хочу запустить как root.

Обновление : небольшая модификация упрощенной функции Денниса Уильямсона, чтобы сделать ее немного проще в использовании:

 salias()
 {
   local a c
   a=$(echo "$1" | cut -f1 -d=)
   c=$(echo "$1" | cut -f2- -d=)
   alias $a="$c"
   alias s$a="sudo $c"
 }

Это означает, что я просто должен поставить «s» перед всей командой. Вместо того:

alias pd='perl -Ilib -I/home/myuser/lib -d'

Я просто добавляю s спереди.

salias pd='perl -Ilib -I/home/myuser/lib -d'

И я сделал. Конечно, компьютер выполняет немного больше работы, но для этого и нужен компьютер. :-)

Благодарность!

Tanktalus
источник
Вы можете (или должны быть в состоянии) пометить вещи как принятые, что похоже на пометку их правильно :)
Билл Вайс,
Правильно - я хочу пометить два ответа как правильные :-P
Tanktalus
3
Почему не ответ Слиззереда? alias sudo="sudo "работает отлично.
trusktr
3

Разве не было бы проще просто взломать скрипт, включающий ваши параметры, а затем поместить его где-нибудь в одну из папок, которая является путем для обычной учетной записи и root? Это действительно не займет много сценария.

#!/bin/bash
exec perl -Ilib -I/home/myuser/lib -d $*
Zoredache
источник
На самом деле это должен быть "$ @" вместо $ *, и это одна из причин, по которой я обычно стараюсь избегать этого. ;-) Это работает, это просто тратит кучу дискового пространства относительно того, что оно содержит.
Tanktalus
3

Это грубо, но это работает здесь:

houdini@clanspum:~/ > alias fb
fb='echo foo bar'
houdini@clanspum:~/ > alias fb | awk -F\' '{print $2}'
echo foo bar
houdini@clanspum:~/ > sudo sh -c "$(alias fb | awk -F\' '{print $2}')"
foo bar
houdini@clanspum:~/ > sudo sh -c "$(alias fb | awk -F\' '{print $2}') a b c"
foo bar a b c
houdini@clanspum:~/ > fb
foo bar
houdini@clanspum:~/ > fb a b c
foo bar a b c
Билл Вайс
источник
Я вставил здесь неполное решение, а затем отредактировал, чтобы исправить. Текущий правильный. Бесплатное голосование первому человеку, который прокомментирует, объясняя, что здесь происходит :)
Билл Вайс,
Я надеялся на более простой способ, чем awk, но надеюсь! = Реальность иногда ;-) Очевидно, что "cut -f2 -d \ '" будет работать так же хорошо, как и awk, и будет чуть-чуть короче.
Tanktalus
Да, вырезать будет работать, я всегда забываю об этом.
Билл Вайс
3

Добавьте префикс "sudo" к выбранным псевдонимам и командам изнутри ~/.bashrcтак:

#a regular alias
alias pd='perl -Ilib -I/home/myuser/lib -d'

#sudofy (command id, alias pd - add others to this list)
for cmd in id pd;
      do alias "s$cmd"="sudo $cmd";
done;

источник
Это не работает - вот с чего я начал. Вы пробовали это?
Tanktalus
Хорошая концепция. Я думаю, что alias sudo="sudo "проще, хотя.
trusktr
3

Как выложили несколько раз, сделайте в '.bashrc':

псевдоним sudo = 'sudo'

Причина, по которой объясняется в «man bash» и «псевдониме помощи»:

псевдоним: псевдоним [-p] [имя [= значение] ...] Определение или отображение псевдонимов.

Without arguments, `alias' prints the list of aliases in the reusable
form `alias NAME=VALUE' on standard output.

Otherwise, an alias is defined for each NAME whose VALUE is given.
**A trailing space in VALUE causes the next word to be checked for
alias substitution when the alias is expanded.**
sixerjman
источник
1

Вы хотите что-то вроде этого:

(alias; echo "exec < /dev/tty") | sudo bash  -i
geocar
источник
Я могу ошибаться, но ISTR, что bash -i(я = интерактивный) только v4.0. Так что на более старом сервере, на котором все еще bashзапущен v3, это, скорее всего, приведет к сбою. Но докажите, что я не прав, кто угодно, продолжайте;)
syntaxerror
@syntaxerror - Вы помните неправильно. -iэто оболочка Борна, см. pubs.opengroup.org/onlinepubs/009695399/utilities/sh.html
геокар
Ничего себе, не ожидал получить ответ так скоро для 6+-летнего поста ... Почему да, я мог бы спутать его #!/bin/bash -iпосле Шебанга, что, очевидно, не то же самое (?). Чтобы вырезать Короче говоря, используя historyв bashскрипте (а не на «живой» в командной строке) будет требовать -iвариант, который я не смог заставить работать на сервере с «только» bashv3 установлен. И это факт.
синтаксическая ошибка
1

Я не знаю, лучше ли это делать на производственной коробке, но локально я использую

alias sudo="sudo -E"

Параметр -E ( сохранить среду ) переопределит параметр env_reset в sudoers (5)). Он доступен только в том случае, если соответствующая команда имеет тег SETENV или опция setenv установлена ​​в sudoers (5).

Эдди Б
источник
-1

Можете ли вы добавить псевдоним в корневой каталог .bashrc или просто запустить .bashrc через sudo перед вашей командой?

sudo (. ~yourlogin/.bashrc; pd ./mytool --some params)
Роберт Суишер
источник
1
Хм, это даже не сработало. Это на самом деле довольно близко к некоторым вещам, которые я пробовал выше, но далеко от реального синтаксиса shell / sudo.
Tanktalus