Как отправить переменную во встроенный shell-скрипт?


26

Я запускаю следующий скрипт:

VAR="Test"
sh -c 'echo "Hello $VAR"'

Но я получаю:

# ./test.sh
Hello

Как я могу отправить переменную VARмоего скрипта в оболочку, созданную с помощью sh -c '...'?

Ответы:


44

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

VAR="Test" sh -c 'echo "Hello $VAR"'

VAR="Test"
export VAR
sh -c 'echo "Hello $VAR"'

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

sh -c "echo 'Hello $ VAR'"

вызывая перезагрузку, если вызывается, когда $VARсодержит что-то вроде';reboot #


Не очень практично (у меня есть несколько переменных, и я не хочу, чтобы они были переменными среды), но это работает, спасибо!
Матье Наполи

3
@Matthieu: Они устанавливаются только как переменные окружения для детей вашего процесса , если вас это беспокоит.
Писквор

5
Просто к вашему сведению, вы также можете сделать export var="Test"в одну строку.
user606723

@Piskvor хорошо спасибо за точность, это прекрасно тогда.
Матье Наполи

9

Вот еще один способ передачи переменных sh -c(в качестве позиционных аргументов):

{
VAR="world"
VAR2='!'
sh -c 'echo "Hello ${0}${1}"' "$VAR" "$VAR2"
}

1
(+1) Чтобы держать его в большей степени в соответствии с обычным ожиданием $ 1 $ 2 для переменных скрипта, он может иметь фиктивное значение для $ 0. Это позволит $@работать как положено, например. sh -c 'echo "Hello $@"' _ "$VAR" "$VAR2"`
Питер.O

2
@ Peter.O Вместо того, чтобы использовать «_», я бы использовал «sh» или разумное имя, чтобы дать этой команде, так как это $0отображается в сообщениях об ошибках / предупреждениях оболочкой.
Стефан Шазелас

5

Если вы не хотите экспортировать их как переменные среды, вот прием, который вы могли бы сделать. Сохраните определение variabe в файл .var_init.shи поместите его в свою под-оболочку следующим образом:

.var_init.sh

VAR="Test"

из командной строки:

sh -c ". .var_init.sh && echo \$VAR" # Make sure to properly escape the '$'

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


... илиENV=.var_ini.sh sh -c '...'
Кусалананда

Обратите внимание, что если .var_init.shожидается, что это будет искать в текущем каталоге (в отличие от $PATH), это должно быть написано. ./var_init.sh
Стефан Шазелас
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.