«Команда не найдена» при использовании функции sudo из ~ / .zshrc

будет отображать сегодняшние строки даты в file1.txt

grep "$(date +%Y%m%d)" file1.txt
10
20.10.2016, 16:10
4 ответа

Мне удалось создать многократно используемое сокращение для одного из решений, описанных в ответе Стефана Шазеласа . [Edit: Стефан повторил исходный ярлык Я сделал предложение; описанный здесь код является более новой версией его создания]

Поместите это в свой ~ / .zshrc :

sdo() sudo zsh -c "$functions[$1]" "$@"

Теперь вы можете использовать sdo как " ] sudo только для пользовательских функций ".

Чтобы убедиться, что sdo работает: вы можете опробовать его на пользовательской функции, которая печатает ваше имя пользователя.

➜ birch@server ~/                             
2
27.01.2020, 20:00

sudo запускает команды напрямую, а не через оболочку, и даже если он запускает оболочку для выполнения этой команды, это будет новый вызов оболочки, а не тот, который читает ваш ~/. zshrc (даже если бы он запустил интерактивный shell, он, вероятно, читал бы root ~/.zshrc, а не ваш, если вы не настроили sudo, чтобы не сбрасывать переменную $HOME).

Здесь вам нужно сказать sudo начать новую оболочку zsh и сказать этой оболочке zsh читать ваш ~/. zshrc перед запуском этой функции:

sudo zsh -c '. $0; "$@"' ~/.zshrc findPort 3306

Или:

sudo zsh -c '. $0; findPort 3306' ~/.zshrc

Или поделиться своими текущими функциями zsh с новым zsh, вызываемым sudo:

sudo zsh -c "$(functions); findPort 3306"

Хотя вы можете получить ошибку arg list too long, если у вас определено много функций (как при использовании системы завершения). Поэтому вы можете ограничиться функцией findPort (и всеми другими функциями, на которые она опирается, если таковые имеются):

sudo zsh -c "$(functions findPort); findPort 3306"

Вы также можете сделать:

sudo zsh -c "(){$functions[findPort]} 3306"

Встроить код функции findPort в анонимную функцию, которой вы передадите аргумент 3306. Или даже:

sudo zsh -c "$functions[findPort]" findPort 3306

(инлайн-скрипт, переданный в -c - это тело функции).

Можно использовать вспомогательную функцию, например:

zsudo() sudo zsh -c "$functions[$1]" "$@"

Не используйте:

sdo() { sudo zsh -c "(){$functions[$1]} ${@:2}" }

Поскольку аргументы sdo подвергнутся еще одному уровню разбора оболочки. Compare:

$ e() echo "$@"
$ sdo e 'tname;uname'
tname
Linux
$ zsudo e 'tname;uname'
tname;uname
14
27.01.2020, 20:00

Для меня очень простым решением было вызвать интерактивную оболочку с помощью sudo -s , которая, похоже, работает с моей версией zsh (5.2) в комплекте с macOS. Это дает мне функции из моего ~ / .zshrc .

Из справочной страницы sudo, которая на самом деле не намекает на такое поведение:

-s, --shell
Запустить оболочку, указанную переменной среды SHELL, если она установлена, или оболочка, заданная записью базы данных паролей вызывающего пользователя. Если указана команда , она передается в оболочку для выполнения с помощью параметра -c оболочки. Если команда не указана, выполняется интерактивная оболочка.

Я не уверен, каков ваш вариант использования, но подозреваю, что вы ищете интерактивное решение.

3
27.01.2020, 20:00

Мне кажется, это работает:

function sudo (){
  args="$@"
  /run/wrappers/bin/sudo -u "$USER" zsh -i -c "$args"
}
0
27.01.2020, 20:00

Теги

Похожие вопросы