ทีนี้"$@"
ขยายไปยังรายการพารามิเตอร์ตำแหน่งหนึ่งอาร์กิวเมนต์ต่อพารามิเตอร์ตำแหน่ง
เมื่อคุณทำ:
set '' 'foo bar' $'blah\nblah'
cmd "$@"
cmd
จะถูกเรียกด้วยทั้ง 3 ข้อโต้แย้ง: สตริงที่ว่างเปล่า, และfoo bar
blah<newline>blah
เชลล์จะเรียกการเรียกของexecve()
ระบบด้วยสิ่งต่อไปนี้:
execve("/path/to/cmd", ["cmd", "", "foo bar", "blah\nblah"], [envvars...]);
หากคุณต้องการสร้างบรรทัดคำสั่งเชลล์ใหม่ (นั่นคือรหัสในภาษาของเชลล์) ที่จะทำให้เกิดการเรียกใช้ซ้ำนั้นคุณสามารถทำสิ่งต่อไปนี้:
awk -v q="'" '
function shellquote(s) {
gsub(q, q "\\" q q, s)
return q s q
}
BEGIN {
for (i = 1; i < ARGC; i++) {
printf "%s", sep shellquote(ARGV[i])
sep = " "
}
printf "\n"
}' cmd "$@"
หรือด้วยการzsh
ขอคำพูดประเภทต่าง ๆ :
$ set '' 'foo bar' $'blah\nblah'
$ print -r -- cmd "${(q)@}"
cmd '' foo\ bar blah$'\n'blah
$ print -r -- cmd "${(qq)@}"
cmd '' 'foo bar' 'blah
blah'
$ print -r -- cmd "${(qqq)@}"
cmd "" "foo bar" "blah
blah"
$ print -r -- cmd "${(qqqq)@}"
cmd $'' $'foo bar' $'blah\nblah'
หรือด้วยzsh
, bash
หรือksh93
(ที่นี่เพื่อbash
, YMMV กับกระสุนอื่น ๆ ):
$ set '' 'foo bar' $'blah\nblah'
$ printf cmd; printf ' %q' "$@"; printf '\n'
cmd '' foo\ bar $'blah\nblah'
คุณสามารถใช้ตัวเลือก xtrace ของเชลล์ที่ทำให้เชลล์พิมพ์สิ่งที่มันจะดำเนินการ:
$ (PS4=; set -x; : cmd "$@")
: cmd '' 'foo bar' 'blah
blah'
ด้านบนเรารัน:
คำสั่ง no-op ด้วยcmd
และพารามิเตอร์ตำแหน่งเป็นอาร์กิวเมนต์ เปลือกของฉันพิมพ์พวกเขาในรูปแบบที่ยกมาดีเหมาะสำหรับ reinput กับเปลือก กระสุนไม่ได้ทำอย่างนั้น
$
ขยายและเครื่องหมายคำพูดคู่อื่น ๆ นั่นเป็นเหตุผลที่คำตอบอื่น ๆ ใช้เครื่องหมายคำพูดเดี่ยวในขณะที่มีความยาวเพื่อจัดการอัญประกาศเดี่ยวภายในสตริงหรือใช้คุณลักษณะของเชลล์เองในการสร้างสำเนาที่ยกมาของสตริง