Як надіслати змінну до вбудованого сценарію оболонки?


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 "ехо" Привіт $ VAR ""

викликає перезавантаження, якщо викликається, коли $VARмістить щось подібне';reboot #


Насправді не практично (у мене є кілька змінних, і я не хочу, щоб вони були змінними середовища), але це працює, дякую!
Матьє Наполі

3
@Matthieu: Вони встановлюються лише як змінні середовища для дітей вашого процесу , якщо саме це вас хвилює.
Пісквор

5
Просто FYI, Ви також можете робити export var="Test"в один рядок.
user606723

@Piskvor добре дякую за точність, це ідеально тоді.
Матьє Наполі

9

Ось ще один спосіб передачі змінних sh -c(як позиційних аргументів):

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

1
(+1) Щоб це більше відповідало нормальному очікуванню $ 1 $ на змінні сценарію, воно може мати фіктивне значення $ 0. Це дозволить $@працювати так, як очікувалося, наприклад. sh -c 'echo "Hello $@"' _ "$VAR" "$VAR2"`
Пітер.O

2
@ Peter.O Замість того, щоб використовувати "_", я би використовував "sh" або розумне ім'я, щоб дати цій команді, оскільки $0це відображається в повідомленнях про помилки / попередження оболонкою.
Стефан Шазелас

5

Якщо ви не хочете експортувати їх як змінні середовища, ось вам можна зробити трюк. Збережіть своє значення змінної у файлі .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
Stéphane Chazelas
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.