ทางเลือกเป็นของคุณ หากคุณไม่ได้อ้างอิงค่า$@
ใด ๆ ของมันจะได้รับการขยายและตีความเพิ่มเติม หากคุณอ้างถึงมันอาร์กิวเมนต์ทั้งหมดที่ส่งผ่านฟังก์ชันจะทำซ้ำในคำต่อคำแบบขยาย คุณจะไม่สามารถจัดการกับโทเค็นไวยากรณ์ของเชลล์เช่น&>|
และอื่น ๆได้อย่างน่าเชื่อถือไม่ว่าจะด้วยวิธีใดโดยไม่ต้องแยกวิเคราะห์อาร์กิวเมนต์ด้วยตัวเอง - ดังนั้นคุณจึงเหลือทางเลือกที่เหมาะสมกว่าในการมอบฟังก์ชั่นของคุณ
"$@"
ว่าคำที่ใช้ในการดำเนินการของคำสั่งง่ายๆเดียวกับ
...หรือ...
- เวอร์ชันที่ขยายและตีความเพิ่มเติมของอาร์กิวเมนต์ของคุณซึ่งจะถูกนำไปใช้ร่วมกันเป็นคำสั่งง่ายๆด้วย
$@
เท่านั้น
ไม่มีทางผิดถ้ามันเป็นความตั้งใจและหากผลของสิ่งที่คุณเลือกนั้นเป็นที่เข้าใจกันดี ทั้งสองวิธีมีข้อดีมากกว่ากันแม้ว่าข้อดีของข้อสองจะไม่ค่อยมีประโยชน์โดยเฉพาะ ยังคง ...
(run_this(){ $@; }; IFS=@ run_this 'ls@-dl@/tmp')
drwxrwxrwt 22 root root 660 Dec 28 19:58 /tmp
... มันไม่ไร้ประโยชน์เพียงแค่ใช้บ่อย และในbash
เชลล์เนื่องจากbash
ไม่ได้กำหนดค่าเริ่มต้นไว้ที่ตัวแปรสภาพแวดล้อมแม้ว่าจะมีการกำหนดนิยามไว้ในบรรทัดคำสั่งของ builtin พิเศษหรือฟังก์ชันค่าโกลบอลสำหรับ$IFS
ไม่ได้รับผลกระทบและการประกาศเป็นแบบโลคัล เพียงเพื่อrun_this()
โทร
ในทำนองเดียวกัน:
(run_this(){ $@; }; set -f; run_this ls -l \*)
ls: cannot access *: No such file or directory
... การกระจายนั้นยังสามารถกำหนดค่าได้ คำพูดมีจุดประสงค์ - มันไม่ได้เพื่ออะไร หากไม่มีพวกมันการขยายตัวของเชลล์จะได้รับการตีความเพิ่มเติม - การตีความที่กำหนดค่าได้ มันเคยเป็น - กับเปลือกหอยที่เก่าแก่มาก- ซึ่ง$IFS
ถูกนำไปใช้ทั่วโลกกับอินพุตทั้งหมดและไม่ใช่แค่การขยาย ในความเป็นจริงกล่าวว่าเปลือกหอยประพฤติชอบมากไม่ในการที่พวกเขายากจนคำป้อนข้อมูลทั้งหมดเกี่ยวกับค่าของrun_this()
$IFS
ถ้าสิ่งที่คุณกำลังมองหาคือพฤติกรรมของเปลือกที่เก่าแก่มากคุณควรใช้run_this()
ใช้
ฉันไม่ได้มองหามันและฉันก็กดยากมากในขณะนี้เพื่อหาตัวอย่างที่มีประโยชน์สำหรับมัน โดยทั่วไปฉันชอบคำสั่งที่เชลล์ของฉันใช้เป็นคำสั่งที่ฉันพิมพ์ run_that()
และเพื่อให้ได้รับเลือกผมจะเกือบตลอดเวลา ยกเว้นว่า ...
(run_that(){ "$@"; }; IFS=l run_that 'ls' '-ld' '/tmp')
drwxrwxrwt 22 root root 660 Dec 28 19:58 /tmp
สามารถอ้างถึงอะไรก็ได้ คำสั่งจะเรียกใช้ที่ยกมา มันทำงานได้เพราะเมื่อเวลาที่คำสั่งรันจริงคำอินพุตทั้งหมดได้ผ่านการกำจัดเครื่องหมายคำพูดแล้ว- ซึ่งเป็นขั้นตอนสุดท้ายของกระบวนการตีความอินพุตของเชลล์ ดังนั้นความแตกต่างระหว่าง'ls'
และls
สามารถทำได้เฉพาะในขณะที่เชลล์กำลังตีความ - และนั่นเป็นสาเหตุที่การอ้างถึงls
ทำให้มั่นใจได้ว่านามแฝงที่มีชื่อls
จะไม่ถูกแทนที่สำหรับls
คำคำสั่งที่ยกมาของฉัน นอกเหนือจากนั้นสิ่งเดียวที่ส่งผลกระทบต่อคำพูดคือการ delimiting ของคำ(ซึ่งเป็นอย่างไรและทำไม quoting ตัวแปร / input-whitespace ทำงาน)และการแปลความหมายของอักขระและคำที่สงวนไว้
ดังนั้น:
'for' f in ...
do :
done
bash: for: command not found
bash: do: unexpected token 'do'
bash: do: unexpected token 'done'
คุณจะไม่สามารถทำอย่างใดอย่างหนึ่งrun_this()
หรือrun_that()
หรือ
แต่ชื่อฟังก์ชั่นหรือ$PATH
คำสั่ง 'd หรือบิวด์อินจะทำงานได้ดีที่ยกมาหรือไม่ถูกยกมาและนั่นเป็นวิธีการrun_this()
และการrun_that()
ทำงานในสถานที่แรก คุณจะไม่สามารถทำอะไรที่เป็นประโยชน์กับ$<>|&(){}
สิ่งเหล่านี้ สั้นของeval
คือ
(run_that(){ "$@"; }; run_that eval printf '"%s\n"' '"$@"')
eval
printf
"%s\n"
"$@"
แต่ไม่ว่าคุณจะ จำกัด ขอบเขตของคำสั่งง่ายๆโดยอาศัยอำนาจของคำพูดที่คุณใช้(แม้ในขณะที่คุณทำไม่ได้เพราะ$@
การกระทำเช่นคำพูดที่จุดเริ่มต้นของกระบวนการเมื่อคำสั่งจะแยกกันสำหรับ metacharacters) ข้อ จำกัด เดียวกันนี้เป็นจริงของการกำหนดบรรทัดคำสั่งและการเปลี่ยนเส้นทางซึ่ง จำกัด อยู่ที่บรรทัดรับคำสั่งของฟังก์ชัน แต่นั่นไม่ใช่เรื่องใหญ่:
(run_that(){ "$@";}; echo hey | run_that cat)
hey
ฉันสามารถ<
ป้อนข้อมูลได้อย่างง่ายดายหรือ>
เอาต์พุตเช่นเดียวกับที่ฉันเปิดไพพ์
อย่างไรก็ตามในทางกลับกันไม่มีทางที่ถูกหรือผิด - แต่ละวิธีมีการใช้งาน เป็นเพียงที่คุณควรเขียนตามที่คุณตั้งใจจะใช้และคุณควรรู้ว่าคุณตั้งใจจะทำอะไร ไม่ใส่คำพูดที่สามารถมีวัตถุประสงค์ - มิฉะนั้นจะไม่มีจะเป็นคำพูดที่ทุกคน - แต่ถ้าคุณไม่ใช้พวกเขาสำหรับเหตุผลที่ไม่เกี่ยวข้องกับวัตถุประสงค์ของคุณคุณก็เขียนโค้ดที่ไม่ดี ทำในสิ่งที่คุณหมายถึง; ฉันพยายามต่อไป
run_that
พฤติกรรมของแน่นอนสิ่งที่ฉันคาดหวัง (ถ้ามีช่องว่างในเส้นทางไปยังคำสั่ง?) หากคุณต้องการพฤติกรรมอื่น ๆ คุณจะต้องถอนมันออกจากไซต์ที่คุณรู้ว่าข้อมูลคืออะไร? ฉันคาดว่าจะเรียกใช้ฟังก์ชั่นนี้run_that ls -l
ซึ่งใช้งานได้เหมือนกันในทั้งสองเวอร์ชัน มีกรณีที่ทำให้คุณคาดหวังแตกต่างกันหรือไม่?