ทำไมเสียงสะท้อนจึงไม่เรียกว่า / bin / sh -c echo foo เอาท์พุทอะไรเลย


15

ตัวอย่างเช่นขณะที่ใช้งานได้:

$ echo foo
foo

สิ่งนี้ไม่:

$ / bin / sh -c echo foo

ในขณะที่สิ่งนี้ทำ:

$ / bin / sh -c 'echo foo; echo bar '
foo
บาร์

มีคำอธิบายไหม?

คำตอบ:


21

จาก 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

นั่นเป็นส่วนแรกที่จะเข้าใจ กรณีที่สองนั้นง่ายและไม่ต้องการคำอธิบายฉันเดา


2
วิธีที่เป็นไปตามมาตรฐานที่เข้มงวดจะเป็นเช่นนั้นsh -c 'echo $1' echo foo
jlliagre

1
sh -c 'echo "$@"' fnord a b c d ...
zwol

3
IMHO คำอธิบายค่อนข้างดี แต่sh -c 'echo $0' fooไม่ใช่ตัวเลือกที่ดีที่สุดโดยคำนึงถึงว่าผู้ถามทราบแล้วว่าใช้/bin/sh -c 'echo foo; echo bar'งานได้คุณสามารถตอบคำถามโดยอ้างคำสั่งได้/bin/sh -c 'echo foo'
X3MBoy

1
@ X3MBoy ผู้ถามทราบแล้วว่า / bin / sh -c 'echo foo' ใช้งานได้ดี เขาต้องการที่จะสะท้อนบางสิ่งบางอย่างนอกเหนือจากที่ฉันอธิบาย
Ijaz Ahmad Khan

18
$ echo foo
foo

การเรียกechoด้วยอาร์กิวเมนต์fooและfooจะถูกพิมพ์

$ /bin/sh -c echo foo

นี้เรียกเปลือกที่มีการโต้แย้งechoและให้ฟู$0เป็นอาร์กิวเมนต์ echooutputs บรรทัดใหม่และคุณทิ้ง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

8

ในคำสั่งนี้:

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'ซึ่งถูกตีความทั้งหมดเป็นหนึ่งอาร์กิวเมนต์ เป็น "สตริงคำสั่ง"


3

โครงสร้าง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

ข้อสรุป

คงคำสั่งที่เรียกใช้งานเป็น "คำ" หนึ่งคำโดยใช้การอ้างอิง

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