ตัวอย่างเช่นขณะที่ใช้งานได้:
$ echo foo foo
สิ่งนี้ไม่:
$ / bin / sh -c echo foo
ในขณะที่สิ่งนี้ทำ:
$ / bin / sh -c 'echo foo; echo bar ' foo บาร์
มีคำอธิบายไหม?
ตัวอย่างเช่นขณะที่ใช้งานได้:
$ echo foo foo
สิ่งนี้ไม่:
$ / bin / sh -c echo foo
ในขณะที่สิ่งนี้ทำ:
$ / bin / sh -c 'echo foo; echo bar ' foo บาร์
มีคำอธิบายไหม?
คำตอบ:
จาก man sh
-c string If the -c option is present, then commands are read from string.
If there are arguments after the string, they are assigned to the
positional parameters, starting with $0
หมายความว่าคำสั่งของคุณควรเป็นเช่นนี้:
$ sh -c 'echo "$0"' foo
foo
ในทำนองเดียวกัน:
$ sh -c 'echo "$0 $1"' foo bar
foo bar
นั่นเป็นส่วนแรกที่จะเข้าใจ กรณีที่สองนั้นง่ายและไม่ต้องการคำอธิบายฉันเดา
sh -c 'echo "$@"' fnord a b c d ...
sh -c 'echo $0' foo
ไม่ใช่ตัวเลือกที่ดีที่สุดโดยคำนึงถึงว่าผู้ถามทราบแล้วว่าใช้/bin/sh -c 'echo foo; echo bar'
งานได้คุณสามารถตอบคำถามโดยอ้างคำสั่งได้/bin/sh -c 'echo foo'
$ echo foo
foo
การเรียกecho
ด้วยอาร์กิวเมนต์fooและfooจะถูกพิมพ์
$ /bin/sh -c echo foo
นี้เรียกเปลือกที่มีการโต้แย้งecho
และให้ฟู$0
เป็นอาร์กิวเมนต์
echo
outputs บรรทัดใหม่และคุณทิ้งfoo หากคุณต้องการที่จะแสดงผลfooให้อ้างอาร์กิวเมนต์:
sh -c 'echo foo'
หรือใช้อาร์กิวเมนต์ที่ให้ไว้:
sh -c 'echo $0' foo
ในตัวอย่างนี้
$ /bin/sh -c 'echo foo; echo bar'
foo
bar
เชลล์ถูกเรียกใช้พร้อมกับอาร์กิวเมนต์echo foo; echo bar
ซึ่งเป็นเอาต์พุต
foo
bar
ในคำสั่งนี้:
echo foo
echo
เป็นไบนารี (หรือคำสั่งในตัว) และfoo
เป็นอาร์กิวเมนต์แรก
ที่นี่:
/bin/sh -c echo foo
/bin/sh
เป็นไบนารีซึ่งมีอาร์กิวเมนต์แรก-c
ซึ่งตัวเองยอมรับ "สตริงคำสั่ง" เป็นพารามิเตอร์ นี่คือecho
ในตัวอย่างข้างต้น จากนั้นก็มีการโต้แย้งที่สามfoo
ซึ่งเป็นอาร์กิวเมนต์สำหรับการไม่ได้สำหรับ/bin/sh
echo
นั่นเป็นเหตุผลในตัวอย่างที่สามของคุณ:
/bin/sh -c 'echo foo; echo bar'
... ทั้งสองพิมพ์ คุณอ้างถึงข้อโต้แย้ง ดังนั้น: อาร์กิวเมนต์แรกคือ-c
และพารามิเตอร์ของอาร์กิวเมนต์นี้'echo foo; echo bar'
ซึ่งถูกตีความทั้งหมดเป็นหนึ่งอาร์กิวเมนต์ เป็น "สตริงคำสั่ง"
โครงสร้างsh -c word
เรียกใช้คำเพียงคำเดียว (ในเชลล์)
คำที่เพิ่มเข้ามาหมายถึงสิ่งอื่น ๆ เช่นอาร์กิวเมนต์ศูนย์หนึ่งสองและอื่น ๆ :
sh -c word zero one two three
เพื่อให้คำสั่งที่มีช่องว่างเป็นหนึ่งคำจำเป็นต้องมีการอ้างถึง:
sh -c 'echo fnord' zero one two three
ดังนั้นสิ่งนี้จะพิมพ์อาร์กิวเมนต์ทั้งหมด:
$ sh -c 'echo "args=" "$0" "$@"' zero one two three
args = zero one two three
ในตัวอย่างที่คุณนำเสนอ: /bin/sh -c echo foo
คำแรก (หลังจากตัวเลือก) คือecho
นั่นคือสิ่งที่ถูกดำเนินการ และเสียงก้องที่ไม่มีข้อความจะพิมพ์บรรทัดใหม่เท่านั้นไม่มีอะไรอื่น:
$ / bin / sh -c echo foo
นั่นคือเหตุผลที่คุณได้รับบรรทัดว่างเปล่า
หากคุณอ้างอิงช่องว่างคุณจะเรียกใช้ "หนึ่งคำ" (ไม่มีช่องว่าง) เช่นนี้:
$ / bin / sh -c echo \ foo foo $ / bin / sh -c "echo foo" foo $ / bin / sh -c 'echo foo' foo
คงคำสั่งที่เรียกใช้งานเป็น "คำ" หนึ่งคำโดยใช้การอ้างอิง
sh -c 'echo $1' echo foo