Jak wysłać zmienną do wbudowanego skryptu powłoki?

26

Uruchamiam następujący skrypt:

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

Ale dostaję:

# ./test.sh
Hello

Jak mogę wysłać zmienną VARmojego skryptu do utworzonej powłoki sh -c '...'?

Matthieu Napoli
źródło

Odpowiedzi:

44

Użyj go, exportaby przekształcić go w zmienną środowiskową, lub przekaż go bezpośrednio do polecenia.

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

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

Unikaj stosowania podwójnych cudzysłowów wokół kodu powłoki, aby umożliwić interpolację, ponieważ wprowadza to luki w iniekcjach poleceń, takie jak:

sh -c „echo„ Hello $ VAR ””

powodując restart, jeśli zostanie wywołany, gdy $VARzawiera coś takiego';reboot #

Ignacio Vazquez-Abrams
źródło
Niezbyt praktyczne (mam kilka zmiennych i nie chcę, żeby były zmiennymi środowiskowymi), ale działa, dzięki!
Matthieu Napoli
3
@ Matthieu: Są one ustawione jako zmienne środowiskowe tylko dla dzieci twojego procesu , jeśli to cię martwi.
Piskvor
5
Tylko do Twojej wiadomości, możesz to zrobić export var="Test"w jednym wierszu.
user606723,
@Piskvor dziękuję za precyzję, która jest idealna.
Matthieu Napoli
9

Oto jeszcze inny sposób przekazywania zmiennych sh -c(jako argumentów pozycyjnych):

{
VAR="world"
VAR2='!'
sh -c 'echo "Hello ${0}${1}"' "$VAR" "$VAR2"
}
ben
źródło
1
(+1) Aby zachować zgodność z normalnymi oczekiwaniami 1 $ 2 $ dla zmiennych skryptu, może mieć wartość zerową dla 0 $. Umożliwi $@to pracę zgodnie z oczekiwaniami, np. sh -c 'echo "Hello $@"' _ "$VAR" "$VAR2"`
Peter.O
2
@ Peter.O Zamiast używać „_”, użyłbym „sh” lub rozsądnej nazwy, aby nadać temu poleceniu, ponieważ $0jest ono wyświetlane w komunikatach o błędach / ostrzeżeniach przez powłokę.
Stéphane Chazelas
5

Jeśli nie chcesz eksportować ich jako zmiennych środowiskowych, oto sztuczka, którą możesz zrobić. Zapisz definicję variabe w pliku .var_init.shi umieść ją w podpowłoce w następujący sposób:

.var_init.sh

VAR="Test"

z linii poleceń:

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

W ten sposób ustawiasz zmienne tylko przy wykonywaniu podpowłoki.

rahmu
źródło
... lubENV=.var_ini.sh sh -c '...'
Kusalananda
Zauważ, że jeśli .var_init.shoczekuje się tego w bieżącym katalogu (w przeciwieństwie do $PATH), należy napisać. ./var_init.sh
Stéphane Chazelas