У меня есть сценарий, который выполняет множество разных задач, большинство из которых не требует каких-либо особых привилегий. Тем не менее, один конкретный раздел, который я содержал в функции, нуждается в привилегиях суперпользователя.
Я не хочу требовать, чтобы весь сценарий выполнялся от имени пользователя root, и я хочу иметь возможность вызывать эту функцию с правами root изнутри сценария. Запрос пароля в случае необходимости не является проблемой, так как в любом случае он в основном интерактивный. Однако, когда я пытаюсь использовать sudo functionx
, я получаю:
sudo: functionx: command not found
Как я и ожидал, export
ничего не изменилось. Я хотел бы иметь возможность выполнять функцию непосредственно в сценарии, а не разбивать ее и выполнять как отдельный сценарий по ряду причин.
Есть ли способ, которым я могу сделать свою функцию "видимой" для sudo, не распаковывая ее, не находя соответствующий каталог, а затем выполняя его как отдельный скрипт?
Функция сама по себе имеет длину страницы и содержит несколько строк, некоторые в двойных кавычках, а некоторые в одинарных кавычках. Это также зависит от функции меню, определенной в другом месте основного скрипта.
Я бы только ожидал, что кто-то с sudo ЛЮБОЙ сможет запустить функцию, так как одна из вещей, которую он делает - это смена паролей.
declare
их тоже.Ответы:
Я признаю, что не существует простого, интуитивного способа сделать это, и это немного хаккей. Но вы можете сделать это так:
Или проще:
Меня устраивает:
По сути,
declare -f
вернет содержимое функции, которую вы затем передадитеbash -c
inline.Если вы хотите экспортировать все функции из внешнего экземпляра bash, измените
FUNC=$(declare -f hello)
наFUNC=$(declare -f)
.редактировать
Чтобы обратиться к комментариям о цитировании, посмотрите этот пример:
источник
echo "Hello!"
фактически совпадает сecho Hello!
(т.е. двойные кавычки не имеют значения для этой конкретной команды эха). Во многих / большинстве других случаев двойные кавычки в функции могут нарушитьbash -c
команду.bash -xc
а не простоbash -c
) и, похоже ,bash
является достаточно умны , чтобы повторно цитатой вещи в этой ситуации, даже в той степени , заменив двойные кавычки одинарные кавычки и изменения'
в'\''
случае необходимости. Я уверен, что будут некоторые случаи, которые он не может обработать, но он определенно работает по крайней мере для простых и умеренно сложных случаев - например, попробуйтеfunction hello() { filename="this is a 'filename' with single quotes and spaces" ; echo "$filename" ; } ; FUNC=$(declare -f hello) ; bash -xc "$FUNC ; hello"
declare -f
выводит определение функции способом, который может быть повторно проанализирован bash, поэтомуbash -c "$(declare -f)"
он работает правильно (при условии, что внешняя оболочка также является bash). Пример, который вы опубликовали, показывает, что он работает правильно - там, где были изменены кавычки, находится след , потому что bash выводит следы в синтаксисе оболочки, например, попытайтесьbash -xc 'echo "hello world"'
sudo yourFunction
не найдены ли (в противном случае вы получите ошибку сегментации из рекурсии)«Проблема» заключается в том, что
sudo
очищает среду (за исключением нескольких допустимых переменных) и устанавливает для некоторых переменных заранее определенные безопасные значения для защиты от угроз безопасности. другими словами, это на самом деле не проблема. Это особенность.Например, если вы установили
PATH="/path/to/myevildirectory:$PATH"
иsudo
не установили PATH в предварительно определенное значение, то любой сценарий, в котором не указано полное имя пути для ВСЕХ команд, которые он выполняет (т. Е. Большинство сценариев), будет смотреть/path/to/myevildirectory
перед любым другим каталогом. Поместите туда такие команды, какls
илиgrep
или другие распространенные инструменты, и вы можете легко делать все, что вам нравится в системе.Самый простой / лучший способ - переписать функцию в виде скрипта и сохранить ее где-нибудь в пути (или указать полный путь к скрипту в
sudo
командной строке - что вам нужно будет сделать в любом случае, еслиsudo
не настроено, чтобы позволить вам запустить ЛЮБУЮ команду как root) и сделать ее исполняемой сchmod +x /path/to/scriptname.sh
Переписать функцию оболочки как скрипт так же просто, как просто сохранить команды внутри определения функции в файл (без строк и
function ...
,{
и}
).источник
sudo -E
избегает очистки окружающей среды.Я написал свою собственную
Sudo
функцию bash для этого, она работает для вызова функций и псевдонимов:источник
Вы можете комбинировать функции и псевдонимы
Пример:
потом
sudo hello
работаетисточник
Вот вариант ответа Уилла . Это включает в себя дополнительный
cat
процесс, но предлагает комфорт heredoc. В двух словах это выглядит так:Если вы хотите больше пищи для размышлений, попробуйте это:
Выход:
Здесь у нас есть
menu
функция, соответствующая функции в вопросе, которая «определена в другом месте в основном скрипте». Если «в другом месте» означает, что его определение уже прочитано на данном этапе, когда выполняется функция, требующаяsudo
выполнения, то ситуация аналогична. Но это, возможно, еще не было прочитано. Может быть другая функция, которая все же вызовет ее определение. В этом случаеdeclare -f menu
его необходимо заменить чем-то более сложным, либо весь скрипт должен быть исправлен так, чтобыmenu
функция уже была объявлена.источник
menu
функция была бы объявлена до этого момента, какf
вызывается из меню.Предполагая, что ваш скрипт либо (а) автономен, либо (б) может получать свои компоненты на основе своего местоположения (вместо того, чтобы помнить, где находится ваш домашний каталог), вы можете сделать что-то вроде этого:
$0
путь к сценарию, используя его вsudo
команде, и передайте параметр, который будет проверяться сценарием, для вызова обновления пароля. Пока вы полагаетесь на поиск сценария по пути (а не просто при запуске./myscript
), вы должны получить абсолютный путь в$0
.sudo
запускает скрипт, он имеет доступ к функциям, которые ему необходимы в скрипте.uid
и поймет, что он был запущен от имени пользователя root , и увидит, что у него есть опция, позволяющая ему обновить пароль, перейти и сделать тот.Скрипты могут повторяться по разным причинам: одна из них - изменение привилегий.
источник