ฉันรันสคริปต์ต่อไปนี้:
VAR="Test"
sh -c 'echo "Hello $VAR"'
แต่ฉันได้รับ:
# ./test.sh
Hello
ฉันจะส่งตัวแปรVAR
ของสคริปต์ไปยังเชลล์ที่สร้างด้วยได้sh -c '...'
อย่างไร?
ฉันรันสคริปต์ต่อไปนี้:
VAR="Test"
sh -c 'echo "Hello $VAR"'
แต่ฉันได้รับ:
# ./test.sh
Hello
ฉันจะส่งตัวแปรVAR
ของสคริปต์ไปยังเชลล์ที่สร้างด้วยได้sh -c '...'
อย่างไร?
คำตอบ:
ใช้export
เพื่อแปลงให้เป็นตัวแปรสภาพแวดล้อมหรือส่งโดยตรงไปยังคำสั่ง
VAR="Test" sh -c 'echo "Hello $VAR"'
VAR="Test"
export VAR
sh -c 'echo "Hello $VAR"'
หลีกเลี่ยงการใช้เครื่องหมายคำพูดคู่รอบรหัสเชลล์เพื่อให้สามารถแก้ไขได้เนื่องจากมีการแนะนำช่องโหว่การฉีดคำสั่งเช่น:
sh -c "echo 'Hello $ VAR'"
ก่อให้เกิดการรีบูตถ้าเรียกว่าเมื่อ$VAR
มีสิ่งที่ชอบ';reboot #
export var="Test"
ในหนึ่งบรรทัด
นี่เป็นอีกวิธีในการส่งผ่านตัวแปรไปยังsh -c
(เป็นอาร์กิวเมนต์ตำแหน่ง):
{
VAR="world"
VAR2='!'
sh -c 'echo "Hello ${0}${1}"' "$VAR" "$VAR2"
}
$@
สามารถทำงานได้ตามที่คาดไว้เช่น sh -c 'echo "Hello $@"' _ "$VAR" "$VAR2"
`
$0
มันจะแสดงในข้อความแสดงข้อผิดพลาด / ข้อความเตือนโดยเชลล์
หากคุณไม่ต้องการส่งออกเป็นตัวแปรสภาพแวดล้อมนี่เป็นเคล็ดลับที่คุณสามารถทำได้ บันทึกคำจำกัดความ variabe ของคุณไปยังไฟล์.var_init.sh
และแหล่งที่มาในเปลือกย่อยของคุณเช่นนี้:
.var_init.sh
VAR="Test"
จากบรรทัดคำสั่ง:
sh -c ". .var_init.sh && echo \$VAR" # Make sure to properly escape the '$'
ด้วยวิธีนี้คุณจะตั้งค่าตัวแปรของคุณที่การดำเนินการของ subshell ของคุณเท่านั้น
ENV=.var_ini.sh sh -c '...'
.var_init.sh
คาดว่าจะมีการค้นหาในไดเรกทอรีปัจจุบัน (ตรงข้ามกับ$PATH
) ก็ควรจะเขียน. ./var_init.sh