จะส่งตัวแปรไปยังเชลล์สคริปต์ได้อย่างไร


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 #


ใช้งานไม่ได้จริง ๆ (ฉันมีหลายตัวแปรและฉันไม่ต้องการให้มันเป็นตัวแปรสภาพแวดล้อม) แต่ใช้งานได้ขอบคุณ!
Matthieu Napoli

3
@ Matthieu: พวกเขาจะถูกตั้งค่าเป็นตัวแปรสภาพแวดล้อมสำหรับเด็กของกระบวนการของคุณเท่านั้นถ้านั่นเป็นสิ่งที่คุณกังวล
Piskvor

5
เพียงแค่ FYI คุณสามารถทำได้export var="Test"ในหนึ่งบรรทัด
user606723

@Piskvor ดีขอบคุณสำหรับความแม่นยำที่สมบูรณ์แบบแล้ว
Matthieu Napoli

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"`
Peter.O

2
@ Peter.O แทนที่จะใช้ "_" ฉันจะใช้ "sh" หรือชื่อที่สมเหตุสมผลในการให้คำสั่งนั้นเนื่องจาก$0มันจะแสดงในข้อความแสดงข้อผิดพลาด / ข้อความเตือนโดยเชลล์
Stéphane Chazelas

5

หากคุณไม่ต้องการส่งออกเป็นตัวแปรสภาพแวดล้อมนี่เป็นเคล็ดลับที่คุณสามารถทำได้ บันทึกคำจำกัดความ 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 '...'
Kusalananda

โปรดทราบว่าหาก.var_init.shคาดว่าจะมีการค้นหาในไดเรกทอรีปัจจุบัน (ตรงข้ามกับ$PATH) ก็ควรจะเขียน. ./var_init.sh
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.