Ответы:
sudo su -
, который является сложным способом написания sudo -i
, создает нетронутую среду. В этом смысл оболочки входа в систему. Даже равнина sudo
удаляет большинство переменных из среды. Кроме того sudo
, это внешняя команда; нет никакого способа повысить привилегии в самом сценарии оболочки, только запустить внешнюю программу ( sudo
) с дополнительными привилегиями, и это означает, что любые переменные оболочки (то есть неэкспортируемые переменные) и функции, определенные в родительской оболочке, не будут доступны в детская оболочка.
Вы можете передавать переменные окружения, не вызывая оболочку входа ( sudo bash
вместо sudo su -
или sudo -i
) и настраивая sudo для пропуска этих переменных (с файлом Defaults !env_reset
или Defaults env_keep=…
в sudoers
файле). Это не поможет вам для функций (хотя bash имеет функцию экспорта функций, sudo блокирует ее).
Обычный способ поместить ваши функции в дочернюю оболочку - определить их там. Позаботьтесь о цитировании: если вы используете <<EOF
документ здесь, содержимое документа здесь сначала раскрывается родительской оболочкой, а результатом этого расширения становится скрипт, который видит дочерняя оболочка. То есть если ты пишешь
sudo -u "$target_user" -i <<EOF
echo "$(whoami)"
EOF
это отображает имя исходного пользователя, а не целевого пользователя. Чтобы избежать этого первого этапа расширения, заключите здесь маркер документа после <<
оператора:
sudo -u "$target_user" -i <<'EOF'
echo "$(whoami)"
EOF
Поэтому, если вам не нужно передавать данные из родительской оболочки в дочернюю оболочку, вы можете использовать приведенный здесь документ:
#!/bin/bash
sudo -u "$target_user" -i <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}"
EOF
Хотя вы можете использовать маркер документа без кавычек для передачи данных из родительской оболочки в дочернюю оболочку, это работает только в том случае, если данные не содержат специальных символов. Это потому, что в сценарии, как
sudo -u "$target_user" -i <<EOF
echo "$(whoami)"
EOF
вывод whoami
становится немного кода оболочки, а не строки. Например, если whoami
команда вернулась, "; rm -rf /; "true
дочерняя оболочка выполнит команду echo ""; rm -rf /; "true"
.
Если вам нужно передать данные из родительской оболочки, простой способ - передать их в качестве аргументов. Вызовите дочернюю оболочку явно и передайте ей позиционные параметры:
#!/bin/bash
extVAR="yourName"
sudo -u "$target_user" -i sh _ "$extVAR" <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}" "${1}"
EOF
Если вам нужно передать несколько переменных, будет удобнее передавать их по имени. Вызов env
явно, чтобы установить переменные окружения для дочерней оболочки.
#!/bin/bash
extVAR="yourName"
sudo -u "$target_user" -i env extVAR="$extVAR" sh <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}" "${1}"
EOF
Обратите внимание, что если вы ожидали, /etc/profile
что целевой пользователь ~/.profile
будет прочитан, вам придется прочитать их явно или вызвать bash --login
вместо sh
.
Это не работает, потому что функция log_f
не объявлена в sudo su -
оболочке, которую вы запускаете. Вместо:
extVAR="yourName"
sudo su - <user> << EOF
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f ${intVAR} ${extVAR}
EOF
Вам нужно получить функцию, определенную в корневом подоболочке. Это могло бы сделать это, но ... Я не знаю, что делает большинство этого материала. По крайней мере - до тех пор, пока stdin sudo
не su
нуждается и не нуждается в чтении пароля - это должно быть log_f()
объявлено.
Я верю, что вы имеете в виду, кстати, расширить эти значения во входные данные корневой оболочки. Если вы не хотите этого делать, то вам следует цитировать EOF
и сами переменные.
В моем случае мне нужно передать массив в и имел некоторые проблемы, но имел успех через некоторое время на вторя ценности буев к env
-Key и обертыванию намеченного кода bash -c '<intended code>'
, и в основном имеет его воссоздание массива, например .: INNER_KEY=($<env_key>)
.
Например:
#!/usr/bin/env bash
PLUGINS=(foo bar baz)
sudo -u <some-user> -i env PLUGINS="`echo ${PLUGINS[@]}`" sh <<'EOF'
bash -c '
FOO=($PLUGINS);
echo values: \[${FOO[@]}\];
for pl in ${FOO[@]};
do echo value: $pl;
done;
'
EOF
Проблема заключалась в том, что я не мог напрямую сделать что-то вроде следующего (не используя bash -c '...'
):
FOO=($PLUGINS);
for pl in ${FOO[@]};
...