为什么这个ffmpeg命令在bash而不是zsh中起作用?


17

今天我下班回家(在Ubuntu盒子上运行bash),并尝试使用心爱的zsh在本地arch盒子上运行一些代码,命令是否失败?

下面的命令与个人信息和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

它在bash中运行完美,但是在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在这里显示您的错误。
斯特凡Chazelas

@cuonglm,我的意思是,当有一个文件匹配该模式时,zsh和bash都将“失败”,因为glob将被扩展。zsh的行为比较聪明,因为当没有匹配项时,它会使您意识到自己的错误。
斯特凡Chazelas

Answers:


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表现得就像zshnomatch选项设置,通过打开failglob

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

更一般而言,您可以禁用外壳文件名生成:

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

(或set -o noglobset +o noglob

或使用一种shell 引用方法使shell对待?和其他模式按字面意义匹配特殊字符。


zsh还提供了noglob内置功能,该功能可通过以下任何命令以任何方式禁用文件名生成:

$ noglob echo *
*

哦,哇!错过了,真是令人尴尬,谢谢您的答复。
John Allard

但是现在这使我产生疑问:有人将如何修复它?通过使用引号?还有别的吗 过于复杂的cat + subshel​​l?如果将其添加到答案中会更好,使它更通用,并且仍然非常完整和正确。
Ismael Miguel

现在,这是一个了不起的答案!我已经相应地投票了。答案确实缺乏最后一点。它告诉您出了什么问题,但没有解决。谢谢。
Ismael Miguel

另一种替代方法:在zsh中,可以通过noglob在命令前添加命令来仅对当前命令禁用globbing 。例如,noglob echo *将简单地输出*
wjv
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.