Псевдоніми недоступні при використанні судо


159

Я сьогодні грав із псевдонімами і помітив, що псевдоніми, здається, не доступні під час використання 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?


Ви оголосили цей псевдонім у .bashrc на / root /
Luciano Facchinelli

2
@LucianoFacchinelli: /root/.bashrcне читається під час виконання команди через sudo.
Флейм


@Flimm: А що sudo -i?
Evi1M4chine

Відповіді:


250

Додайте до свого рядка наступний рядок ~/.bashrc:

alias sudo='sudo '

З посібника з bash :

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

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

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


18
Досить приємне рішення.
улідко

Таким чином, проблема в основному зводиться до того, що sudo просто запрограмований таким чином, що він не перевіряє псевдонім, тому ll не знайдеться?
kemra102

2
Читання документації, очевидно, приносить користь
багатому

4
Чи зламається це, якщо я буду використовувати прапор судо, наприклад sudo -H ll?
Марк Е. Хааз

1
@mehaase Так, я спробував, і він ламається.
користувач31389

5

Я написав для нього функцію Bash, яка тініє sudo.

Він перевіряє, чи є у мене псевдонім для даної команди, і виконує команду aliase замість буквальної з цим 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файлу, не забудьте його джерело або перезапустити термінальний сеанс після цього, щоб застосувати зміни.


Було б чудово, якби це також працювало для sudo -H ll.
uav

3

Псевдоніми призначені для користувача - їх потрібно визначити в /root/.bashrc


3
Вони вже під /root/.bashrc, тому це не проблема
kemra102

1
Відповідь на це питання буде єдино правильним для ситуації , коли ви запускаєте оболонку себе як корінь, так як з sudo -sабо sudo -iтільки якщо запустити сам по собі , щоб отримати кореневу оболонку, а НЕ з sudo -s command...або sudo -i command...формами) або sudo bashабо sudo su, або в ситуації , коли ви увімкнено кореневі логіни і таким чином є коренева оболонка. Коли користувач, що не має коренів, працює sudo command...з власної оболонки, розширення псевдоніму здійснюється за допомогою власної некористової оболонки. sudoне розширює псевдоніми, тому що стосується ситуації, описаної у питанні , ця відповідь є невірною.
Елія Каган

3

@Alvins відповідь найкоротший. Без сумніву! :-)

Однак я думав про командному рядку рішення для виконання не згладжені команд в Судо , де немає необхідності заново 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як псевдонім.


3
Це може бути простіше, якщо ви використовували aliasвбудований, оскільки його вихід чистіший. alias llвиходи alias ll='ls -ahlF'.
муру

Ось версія включення пропозиції @ Мура в: alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudo.
ACK_stoverflow

Я думаю, що в первісному питанні питання полягало в тому, щоб врятувати роботу, не sudo -iспочатку, запустити команду aliase, але зробити це відразу. Наявність такої складної команди перемагає це. Ви могли просто зробити колишнє, і бути набагато швидшим.
Evi1M4chine

1

У мене є ще одне приємне рішення, яке також додає трохи довіри:

Використовуйте 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

Потім увійдіть у новий термінал, і вам слід добре зайти.


Існує спосіб отримати список псевдонімів, особливо призначених для завершення:compgen -a
muru

@muru: Дякую, але в цьому випадку мені потрібні значення, а не ключі. Тож те, на що введений псевдонім, буде замінено. Ви вводите псевдонім (наприклад, в sudo ll), натискаєте [TAB ↹], і скрипт знаходить llу списку призначення псевдонімів, вирізає те, що йому призначено, і вставляє його. (Так ви отримаєте напр sudo ls -lahvF --color=auto --time-style=long-iso.)
Evi1M4chine

0

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

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

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. Якщо у вас вже готовий файл псевдонімів, скопіюйте його в це місце

Перезапустіть термінал, і ви добре їхати!


0

Відповідь вгорі - це чудова. Однак якщо ви введете sudo -iі піднімете підказку sudo ( #), у вас не буде псевдонімів, які ви хочете використовувати.

Щоб використовувати псевдоніми (та все інше) у відповідь на #запит, використовуйте:

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

Де "$ PWD" автоматично розширюється на "/ home / YOUR_USER_NAME"


0

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.