ทำไมคำสั่ง ffmpeg นี้ทำงานใน bash ไม่ใช่ zsh?


17

วันนี้ฉันกลับถึงบ้านจากที่ทำงาน (เรียกใช้ทุบตีบนกล่อง Ubuntu) และพยายามที่จะเรียกใช้โค้ดบางอย่างบนกล่องซุ้มประตูท้องถิ่นของฉันด้วย zsh ที่รักของฉันและคำสั่งล้มเหลว?

คำสั่งด้านล่างพร้อมข้อมูลส่วนบุคคลและ ip มีการเปลี่ยนแปลงอย่างชัดเจน

ffmpeg -i rtsp://user:pass@my.webserver.org:5554/my-media/media.amp?videocodec=h264  -threads 3 -vcodec copy -f segment -segment_time 2 outfiles/cam_out%04d.mp4

มันทำงานได้อย่างสมบูรณ์แบบในการทุบตี แต่เมื่อฉันรันใน zsh ฉันได้รับข้อผิดพลาด

zsh: no matches found: rtsp://user:pass@my.webserver.org:5554/my-media/media.amp?videocodec=h264

ทำไม zsh ที่รักของฉันทรยศฉัน


7
ลองใส่ลิงค์ rtsp ลงในเครื่องหมายคำพูดเดี่ยว
jimmij

1
คุณคือฮีโร่ของฉัน :) ฉันรู้ว่า zsh จะไม่ทำให้ฉันผิดหวัง
John Allard

1
ลองใช้หลังจากmkdir -p 'rtsp://user:pass@my.webserver.org:5554/my-media/media.amp-videocodec=h264'นั้นทั้ง bash และ zsh จะทำให้คุณล้มเหลว อย่างน้อย zsh จะแสดงความผิดพลาดของคุณที่นี่
Stéphane Chazelas

@cuonglm ฉันหมายถึงว่าเมื่อมีไฟล์ที่ตรงกับรูปแบบทั้ง zsh และ bash จะ "ล้มเหลว" ในการที่ glob จะถูกขยาย พฤติกรรมของ zsh คือ saner ในเมื่อไม่มีการจับคู่มันทำให้คุณตระหนักถึงความผิดพลาดของคุณ
Stéphane Chazelas

คำตอบ:


43

ในสตริง:

rtsp://user:pass@my.webserver.org:5554/my-media/media.amp?videocodec=h264

คุณมี?ในสตริงนั้นดังนั้นเชลล์จะทำการขยายชื่อพา ธบนสตริงนั้นโดยใช้กฎการจับคู่รูปแบบ

ในbashหากfailglobไม่ได้ตั้งค่าตัวเลือกซึ่งเป็นค่าเริ่มต้นแล้วรูปแบบที่ล้มเหลวจะถูกปล่อยตามที่เป็นอยู่:

$ echo does-not-exist?
does-not-exist?

ในขณะที่zshจะรายงานข้อผิดพลาดการจับคู่รูปแบบกับnomatchชุดตัวเลือกซึ่งเป็นค่าเริ่มต้น

$ echo does-not-exist?
zsh: no matches found: does-not-exist?

คุณสามารถzshระงับข้อผิดพลาดและพิมพ์รูปแบบ:

$ setopt nonomatch
$ echo does-not-exist?
does-not-exist?

คุณสามารถทำให้มีbashพฤติกรรมเช่นเดียวzshกับการnomatchตั้งค่าตัวเลือกโดยการเปิดfailglob:

$ shopt -s failglob
$ echo does-not-exist?
bash: no match: does-not-exist?

โดยทั่วไปคุณสามารถปิดใช้งานการสร้างชื่อไฟล์เชลล์:

$ set -f
$ : "The command"
$ set +f

(หรือset -o noglob, set +o noglob)

หรือใช้หนึ่งในวิธีการอ้างอิงเชลล์เพื่อให้เชลล์ปฏิบัติ?และรูปแบบอื่น ๆ ที่ตรงกับอักขระพิเศษอย่างแท้จริง


zshยังจัดเตรียมnoglobbuiltin ซึ่งปิดใช้งานการสร้างชื่อไฟล์ในคำใด ๆ สำหรับคำสั่งแบบง่ายต่อไปนี้:

$ noglob echo *
*

โอ้ว้าวมันช่างน่าอายที่จะพลาดขอบคุณสำหรับคำตอบที่ดี
John Allard

แต่ตอนนี้มันทำให้ฉันถาม: ใครจะแก้ไขได้อย่างไร โดยใช้คำพูด? อื่น ๆ อีก? Cat + subshells ที่ซับซ้อนเกินไป? มันจะดีถ้าคุณเพิ่มคำตอบลงไปเพื่อทำให้เป็นคำที่กว้างขึ้นและยังสมบูรณ์และถูกต้อง
Ismael Miguel

ตอนนี้นั่นคือคำตอบที่ยอดเยี่ยม! ฉัน upvoted ตาม คำตอบคือไม่มีบิตสุดท้าย มันบอกว่ามีอะไรผิดปกติ แต่ไม่ใช่การแก้ไข ขอขอบคุณ.
Ismael Miguel

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