Как получить команды sudo для использования настроек в /root/.bashrc

9

Я настроил .bashrcнесколько псевдонимов, в частности, llиexport LS_OPTIONS='--color=auto'

К сожалению, это не работает при использовании с sudo, поэтому я также изменил /root/.bashrc, но это, кажется, не имеет значения.

sudo envпоказывает HOME=/rootиSHELL=/bin/bash

Как я могу получить sudoкоманды для использования настроек в /root/.bashrc?

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

Milliways
источник
@ daniel-gelling - я всегда чувствовал, что этот вопрос - проблема XY - meta.stackexchange.com/questions/66377/what-is-the-xy-problem . Название подразумевает, что они хотят что-то из, /root/.bashrcно на самом деле то, что Q следует за псевдонимами из этого файла - это невозможно по этому вопросу - unix.stackexchange.com/questions/1496/… .
SLM
@slm То , что я после добавления метода к Bashrc - как я сделал в моем личном файле .bashrc, а также файл .bashrc для корня к «отключить» в -rопции для crontab: crontab () { [[ $@ =~ -[iel]*r ]] && echo '"r" not allowed' || command crontab "$@" ;}. Это работает, когда вы вошли в систему как любой пользователь, однако, когда я выполняю, sudo crontab -rон все еще выполняется.
Даниэль Геллинг
@DanielGelling - посмотрите, подходит ли мой ответ к вашему сценарию.
SLM

Ответы:

6

sudoзапускает исполняемый файл, а не команду оболочки Так что он не знает об псевдонимах. Если вы запускаете sudo ls, это как sudo /bin/ls, он не использует lsпсевдоним, который у вас может быть.

Вы можете sudo lsрасширить псевдоним, добавив в свой файл следующее .bashrc:

alias sudo='sudo '

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

Кроме того, sudo удаляет большинство переменных из окружения. Это не повлияет на псевдоним, например alias ls='ls $LS_OPTIONS', потому что это переменная оболочки, используемая оболочкой, когда она расширяет команду (и экспорт из нее .bashrcне имеет смысла). Но это повлияет на переменные, которые используются командой, такие как LS_COLORS. Вы можете настроить sudo для сохранения определенных переменных среды, отредактировав его конфигурацию: запустите visudoи добавьте строку

Defaults env_keep += "LS_COLORS"

С этими настройками, sudo llдаст цвета, к которым вы привыкли.

Кроме того, вы можете запустить корневую оболочку с sudo -s. Эта оболочка загрузит свой конфигурационный файл ( ~/.bashrcдля bash). В зависимости от того, как сконфигурирован sudo, он может остаться HOMEв вашем домашнем каталоге или изменить его на /root. Вы можете принудительно установить домашний каталог в корневой каталог с помощью sudo -Hs; и наоборот, чтобы сохранить исходный домашний каталог, запустите sudo env HOME="$HOME" bash.

Жиль "ТАК - прекрати быть злым"
источник
3

Спасибо тем, кто ответил, кто побудил меня прочитать man sudoболее внимательно.

sudo -s Если команда не указана, выполняется интерактивная оболочка.

Эта интерактивная оболочка использует /root/.bashrcи, следовательно, включает в себя мои настройки.

Требуется, чтобы команда вводилась отдельно, но это нормально.

Milliways
источник
2

Фон

Я всегда чувствовал, что этот вопрос - проблема XY . Название подразумевает, что они хотят что-то из этого, /root/.bashrcно на самом деле вопрос заключается в том, какие псевдонимы из этого файла - как полагают, это невозможно - почему мой сценарий Bash не распознает псевдонимы? ,

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

Все, что находится в среде пользователя, не должно восприниматься сценариями и любым программным обеспечением, которое может работать на данном устройстве. Но я понимаю, что есть сценарии, в которых могут быть псевдонимы в определенной учетной записи пользователя, $HOME/.bashrcкоторые другие могут использовать в интерактивных сценариях.

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

пример

Настроить

Для настройки я добавил следующие псевдонимы, переменные среды и функции для моего пользователя root /root/.bashrcи /root/.bash_profileфайлов.

$ grep smurf ~/.bashrc
alias brc_smurf='echo "ran alias from /root/.bashrc"'
export brc_smurf_env='var from /root/.bashrc'
bpf_smurf_func() { echo 'ran func from /root/.bash_profile'; }

$ grep smurf ~/.bash_profile
alias bpf_smurf='echo "ran alias from /root/.bash_profile"'
export bpf_smurf_env='var from /root/.bash_profile'
brc_smurf_func() { echo 'ran func from /root/.bashrc'; }

Ничего не делая ни одной из этих работ (без сюрпризов)

$ sudo brc_smurf
sudo: brc_smurf: command not found

$ sudo bpf_smurf
sudo: bpf_smurf: command not found

Мы видим, что aliasкоманда не показывает псевдонимов при запуске в sudo:

$ sudo alias
$

Такое поведение - ваш намек на то, что вы не должны ожидать, что псевдонимы будут доступны. Но мы продолжаем ...

Шаг № 1 - псевдонимы видны

Если мы запустим, bash -ciмы можем заставить Bash хотя бы прочитать наш $HOME/.bashrc:

$ sudo bash -ci 'alias' | grep smurf
alias brc_smurf='echo "ran alias from /root/.bashrc"'

Круто, так может мы сможем запустить его?

$ sudo bash -ci 'alias; brc_smurf'
bash: alias; brc_smurf: No such file or directory

Шаг 2 - shopt -s expand_aliases

Нет. Опять же, это сделано намеренно, мы делаем что-то, чего не должны делать, поэтому есть ряд «безопасных» функций, которые мы должны отключить. другая «безопасность» - это Bash.

$ sudo bash -ci 'shopt -s expand_aliases; alias; brc_smurf'
alias brc_smurf='echo "ran alias from /root/.bashrc"'
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
ran alias from /root/.bashrc

Здесь мы можем увидеть наше сообщение от /root/.bashrc, мы успешно выполнили псевдоним пользователя root brc_smurf.

Шаг № 3 - как насчет env vars?

Если вы используете метод, показанный выше, теперь это должно работать.

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env'
ran alias from /root/.bashrc
var from /root/.bashrc

Шаг № 4 - как насчет функций?

Эти работы тоже, как и ожидалось:

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env;brc_smurf_func'
ran alias from /root/.bashrc
var from /root/.bashrc
ran func from /root/.bashrc

TLDR;

Вы можете сделать это, чтобы получить доступ к переменным среды + псевдонимам из /root/.bashrc:

$ sudo bash -ci 'shopt -s expand_aliases; <cmds>'

Убирайся

Этот метод позволяет содержимое /root/.bashrc, он не забирает содержимое /root/.bash_profile.

Ссылки

SLM
источник
Да, хотя между ними есть некоторые незначительные различия, давайте не будем вдаваться в детали ;-). В любом случае, не могли бы вы помочь мне с ситуацией, о которой я говорил в комментариях к вопросу: использование функций .bashrcс помощью sudo; специально убрав -rопцию из crontab?
Даниэль Геллинг
Хорошо, но это будет означать, что мне придется бежать: sudo bash -ci 'alias; shopt -s expand_aliases; echo $brc_smurf_env'вместо простого sudo echo $brc_smurf_env?
Даниэль Геллинг
Вы можете удалить то alias, что нужно было просто показать им, что вам нужно будет сделатьsudo bash -ci 'shopt -s expand_aliases; <cmds>'
slm
Было бы много печатать, чтобы отредактировать мой crontab для root. Позвольте мне создать псевдоним для этого :-P
Даниэль Геллинг
@DanielGelling - да, добро пожаловать на все самое веселье в кишечнике.
SLM
0

В файле / etc / sudoers есть несколько настроек, специально предназначенных для настройки среды, в которой запускаются команды sudo (например, проверка того, что PATH имеет только надежные расположения), но в зависимости от того, что вы надеетесь получить из этого. вы не сможете делать то, что вам нужно, если для запуска среды необходимо выполнить реальные команды в оболочке. В частности, Sudoing не дает вам оболочки для входа в систему, поэтому он не настроит для вас обычный профиль.

hvindin
источник
0

Допустим, мы редактируем /root/.bashrc так:

$ sudo su -
Password: ******
# cat ~/.bashrc

echo "root bashrc file was read"
PATH=~/bin:$PATH
echo "$PATH"
export USERVAR=set
echo "$USERVAR"

umask 022
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'

Выйдите из системы и войдите снова, чтобы bash прочитал файл:

# exit
$ sudo su -
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@here:~# alias l
alias l='ls $LS_OPTIONS -lA'
root@here:~# 

Как видите, файл был прочитан, переменная PATH была изменена, а псевдонимы установлены. Все работает по вашему желанию.

Тем не менее, sudo по-прежнему не будет работать, как вы ожидаете.

root@here:~# exit
$ sudo env | grep USERVAR              # no output 
$ sudo env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ПУТЬ не изменился. Могут быть способы изменить путь в sudoers, но я настоятельно рекомендую вам избегать этого. И, в любом случае, псевдонимы, функции и некоторые другие изменения по-прежнему не будут применены при изменении только PATH. Файл должен быть получен. Выполнение этого для каждого сценария или команды попросит компьютер выполнить больше работы без какой-либо реальной выгоды. Скрипты не используют псевдонимы (для них нет практического применения внутри скриптов).

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

Вы можете начать bash так:

$ sudo bash
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@mail:/home/isaac/me/temp/clocks-master#

Но, как вы видите выше, pwd (рабочий каталог) не изменился, и, если вы проверите немного больше, некоторые другие настройки также не изменились. Вот почему правильная команда должна использовать:

$ sudo su -

Если эта команда слишком длинна для ввода, создайте псевдоним или функцию в пользователе (не root), где будет использоваться эта команда, что-то вроде:

$ alias mysu='sudo su -'
$ mysu
# 
Исаак
источник
0

TL; DR: Вы можете использовать sudo -iдля запуска функции , определенной /root/.bashrc(но не псевдоним) , а также имеет доступ к переменным , экспортируемым из этого файла:

аргументы команды sudo -i 

Псевдонимы там не работают, но вы можете легко преобразовать их в функции, если хотите сделать их доступными sudo -i.

Читайте дальше для полного анализа и более подробной информации.


Здесь есть несколько проблем, некоторые в том, как работает sudo, а некоторые в том, как работает сам bash ...

По умолчанию sudoбудет искать только команды и обходить оболочку, поэтому простой запуск sudo llбудет работать, только если llв одном из каталогов находится исполняемый файл $PATH. Итак, чтобы использовать псевдонимы (или функции), вы должны убедиться, что оболочка вызывается как часть процесса.

Одним из способов было бы запустить что-то вроде sudo shили sudo bash, хотя современный sudo(я тестирую это на sudo 1.8.19p1) имеет опции -sи -iдля этой цели.

Таким образом, одна попытка будет выглядеть примерно так sudo -s ll(что эквивалентно sudo bash -c 'll'предположению, что вы $SHELL- Bash, что, кажется, имеет место на основе rcfileупомянутой вами информации). Но это тоже не работает, так как запускает оболочку в неинтерактивном режиме, не входящий в систему режим, который не читает ни один из его файлов запуска. По сути, это то же самое, что если вы пишете сценарий оболочки и используете его #!/bin/bashдля запуска. Псевдонимы (и функции), которые у вас есть ~/.bashrc, не будут доступны из этого скрипта ...

Итак, следующий -iвариант, который создает оболочку входа в систему. Это более перспективно, так как он будет читать ваши файлы запуска! И все же sudo -i ll(эквивалентно sudo bash -l -c 'll') все равно не будет работать. Так как это возможно, учитывая, что он прочитал определение llпсевдонима?

Что ж, следующим объяснением здесь является то, что по умолчанию bash не будет расширять псевдонимы, кроме случаев, когда оболочка является интерактивной ... Эта оболочка, запущенная sudo -i(или bash -l), является оболочкой входа , но все же не интерактивной.

Поэтому следующим шагом является получение интерактивной оболочки, которая затем работает :

sudo bash -i -c 'll'

(Иметь логин и интерактив тоже хорошо, конечно, bash -l -i -c ...будет работать.)

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

sudo bash -l -O expand_aliases -c 'll'

(В случае, когда bash был интерактивным , не требовалась оболочка входа в систему , поскольку этого достаточно для чтения файлов инициализации, но для этого нужно -lих прочитать.)

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

Обратите внимание, что ранее я говорил об псевдонимах и функциях ... Это было сделано специально, поскольку функции здесь намного удобнее. Вам не нужно ничего особенного (например, наличие интерактивной оболочки или установка определенной опции) для выполнения функций в оболочке, если вы используете их определение.

Таким образом , если вы определили llкак функцию вместо псевдонима, вы сможете использовать его непосредственно SUDO в -iярлыке:

sudo -i ll

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

sudo -i ll -C -R /etc

(Сравнить с sudo bash -i -c 'll -C -R /etc'.)

Функции также более гибкие и, как правило, проще в обслуживании ... Обычно псевдоним легко преобразовать в функцию, единственное предостережение - всегда использовать "$@"там, где вы ожидаете получить дополнительные аргументы (обычно в конце псевдоним.)

Например, этот псевдоним:

alias ll='ls $LS_OPTIONS -l'

Может быть превращен в эту функцию:

ll () {
    ls $LS_OPTIONS -l "$@"
}

Для большинства целей они эквивалентны. И, как упоминалось ранее, функция должна быть доступна непосредственно из sudo -i, так что это дополнительный бонус.

Я надеюсь, что вы найдете этот ответ и объяснение полезным!

filbranden
источник
Д.В. - Я не чувствую, что это улучшает ситуацию больше, чем то, что уже здесь.
SLM
1
@slm я думаю , что мой ответ что - то добавить, так как нет ответа на предыдущий вопрос не упомянул форму , sudo -i command argumentsчтобы иметь возможность запускать функции из /root/.bashrcи имеют экспортируемые переменные доступны. Но я вижу, что мой ответ был, возможно, слишком длинным, и эта информация была несколько похоронена там ... Поэтому я добавил TL; DR, чтобы подвести его итог (при этом сохраняя технические детали расследования). Пожалуйста, взгляните еще раз.
августа