Bagaimana cara mengirim variabel ke skrip shell sebaris?

26

Saya menjalankan skrip berikut:

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

Tapi saya mendapatkan:

# ./test.sh
Hello

Bagaimana saya bisa mengirim variabel VARskrip saya ke shell yang dibuat dengan sh -c '...'?

Matthieu Napoli
sumber

Jawaban:

44

Baik digunakan exportuntuk mengubahnya menjadi variabel lingkungan, atau meneruskannya langsung ke perintah.

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

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

Hindari menggunakan tanda kutip ganda di sekitar kode shell untuk memungkinkan interpolasi karena itu memperkenalkan kerentanan injeksi perintah seperti di:

sh -c "echo 'Hello $ VAR'"

menyebabkan reboot jika dipanggil ketika $VARberisi sesuatu seperti';reboot #

Ignacio Vazquez-Abrams
sumber
Tidak terlalu praktis (saya memiliki beberapa variabel, dan saya tidak ingin mereka menjadi variabel lingkungan), tetapi berfungsi, terima kasih!
Matthieu Napoli
3
@ Matthieu: Mereka hanya ditetapkan sebagai variabel lingkungan untuk anak-anak dari proses Anda , jika itu yang membuat Anda khawatir.
Piskvor
5
Cuma FYI, Anda juga bisa melakukannya export var="Test"dalam satu baris.
user606723
@Piskvor juga terima kasih atas ketepatannya, itu sempurna kalau begitu.
Matthieu Napoli
9

Berikut ini cara lain untuk meneruskan variabel ke sh -c(sebagai argumen posisi):

{
VAR="world"
VAR2='!'
sh -c 'echo "Hello ${0}${1}"' "$VAR" "$VAR2"
}
ben
sumber
1
(+1) Agar lebih sejalan dengan ekspektasi normal $ 1 $ 2 untuk variabel skrip, ini dapat memiliki nilai dummy untuk $ 0. Ini akan memungkinkan $@untuk bekerja seperti yang diharapkan, mis. sh -c 'echo "Hello $@"' _ "$VAR" "$VAR2"`
Peter.O
2
@ Peter.O Daripada menggunakan "_", saya akan menggunakan "sh" atau nama yang masuk akal untuk diberikan kepada perintah itu, karena itu $0ditampilkan dalam pesan kesalahan / peringatan oleh shell.
Stéphane Chazelas
5

Jika Anda tidak ingin mengekspornya sebagai variabel lingkungan, inilah trik yang bisa Anda lakukan. Simpan definisi variabe Anda ke file .var_init.shdan sumber di sub-shell Anda seperti ini:

.var_init.sh

VAR="Test"

dari baris perintah:

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

Dengan cara ini, Anda hanya mengatur variabel Anda pada pelaksanaan subkulit Anda.

rahmu
sumber
... atauENV=.var_ini.sh sh -c '...'
Kusalananda
Perhatikan bahwa jika itu .var_init.shdiharapkan untuk dicari dalam direktori saat ini (tidak seperti $PATH), itu harus ditulis. ./var_init.sh
Stéphane Chazelas