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

Сегодня я играл с псевдонимами и заметил, что при использовании 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

Есть ли причина, по которой вы не можете использовать псевдонимы во время использования sudo?

8 ответов

Решение

Добавьте следующую строку в ваш ~/.bashrc:

alias sudo='sudo '

Из руководства по bash:

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

Первое слово каждой простой команды, если оно не заключено в кавычки, проверяется на наличие псевдонима. Если это так, это слово заменяется текстом псевдонима. Символы '/', '$', '`', '=' и любые метасимволы оболочки или символы цитирования, перечисленные выше, могут не отображаться в псевдониме. Текст замены может содержать любые допустимые входные данные оболочки, включая метасимволы оболочки. Первое слово замещающего текста проверяется на псевдонимы, но слово, идентичное расширяемому псевдониму, не раскрывается во второй раз. Это означает, что, например, псевдоним ls можно присвоить "ls -F", и Bash не пытается рекурсивно развернуть текст замены. Если последний символ значения псевдонима является пробелом или символом табуляции, то следующее слово команды, следующее за псевдонимом, также проверяется на расширение псевдонима.

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

Я написал функцию Bash для этого, что тени sudo,

Он проверяет, есть ли у меня псевдоним для данной команды, и запускает команду с псевдонимом вместо литеральной с sudo в таком случае.

Вот моя функция в качестве одной строки:

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

Или красиво отформатирован:

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

Вы можете добавить его в свой .bashrc файл, не забудьте его найти или перезапустить сеанс терминала, чтобы применить изменения.

Псевдонимы зависят от пользователя - их необходимо определить в /root/.bashrc

@Alvins ответ самый короткий. Без сомнения!:-)

Однако я подумал о решении командной строки для выполнения команды псевдонима в sudo, где нет необходимости переопределять sudo с alias команда.

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

Решение

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

пример

В случае с ll команда

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

объяснение

когда у вас есть псевдоним (например: ll) команда type -a возвращает псевдоним

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

с grep в этом случае вы выбираете текст между акцентом `и апострофом ' ls -l

А также xargs выполняет выбранный текст ls -l как параметр sudo,

Да, немного дольше, но полностью чистый;-) Не нужно переопределять sudo как псевдоним.

У меня есть еще одно приятное решение, которое добавляет немного доверия:

Используйте завершение bash, чтобы автоматически заменить слова позади sudo с их псевдонимами при нажатии таб.

Сохранить это как /etc/bash_completion.d/sudo-alias.bashcomp и он должен автоматически загружаться при запуске интерактивной оболочки:

_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

Затем войдите в новый терминал, и вам будет хорошо идти.

@WinEunuuchs2Unix: $PWD расширяется до "настоящего рабочего каталога". Я думаю ты хочешь $HOME,

Кроме того, в большинстве случаев, вероятно, лучше иметь отдельный корневой файл.bashrc. На самом деле, я бы сделал это настоящим файлом в /root, мягкая ссылка на него в домашнем каталоге пользователя (например, .bashrc_root) и получить его от пользователя .bashrc файл. Если через некоторое время эта учетная запись привилегированного пользователя больше не существует, корневой .bashrc файл все еще доступен для других пользователей.

Ответ с лучшим ответом - отличный. Однако если вы введете sudo -i и поднять до приглашения sudo (#) у вас не будет псевдонимов, которые вы хотели бы использовать.

Чтобы использовать ваши псевдонимы (и все остальное) на # подскажите, используйте:

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

Где "$PWD" автоматически раскрывается в "/home/YOUR_USER_NAME"

У меня есть другое решение, в котором вам не нужно добавлять sudo как псевдоним. Я использую Linux Mint 17.3, но он должен быть очень похож на Ubuntu.

Когда вы root, тогда .profile запускается из своего домашнего каталога. Если вы не знаете, что такое домашний каталог в корневом каталоге, вы можете проверить с помощью:

sudo su
echo $HOME

Как видите, дом root является /root/, Проверьте его содержимое:

cd $HOME
ls -al

Там должно быть .profile файл. Откройте файл и добавьте следующие строки:

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

По сути, этот bash-скрипт проверяет файл с именем .bash_aliases, Если файлы присутствуют, он выполняет файл.

Спасти .profile файл и создать псевдонимы в .bash_aliases, Если у вас уже есть файл псевдонимов, скопируйте его в это место

Перезапустите терминал, и вы готовы!

Другие вопросы по тегам