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

Joh*_*ard 18 bash url zsh quoting

今天我下班回家(在 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
Run Code Online (Sandbox Code Playgroud)

它在 bash 中运行完美,但是当我在 zsh 中运行它时出现错误

zsh: no matches found: rtsp://user:pass@my.webserver.org:5554/my-media/media.amp?videocodec=h264
Run Code Online (Sandbox Code Playgroud)

为什么我心爱的zsh背叛了我?

cuo*_*glm 43

在字符串中:

rtsp://user:pass@my.webserver.org:5554/my-media/media.amp?videocodec=h264
Run Code Online (Sandbox Code Playgroud)

?在该字符串中,因此 shell 将使用模式匹配规则对该字符串执行路径名扩展

在 中bash,如果failglob没有设置选项,这是默认设置,则失败的模式将保持原样:

$ echo does-not-exist?
does-not-exist?
Run Code Online (Sandbox Code Playgroud)

设置选项时,虽然zsh不会报告模式匹配错误nomatch,这是默认值:

$ echo does-not-exist?
zsh: no matches found: does-not-exist?
Run Code Online (Sandbox Code Playgroud)

您可以zsh抑制错误并打印模式:

$ setopt nonomatch
$ echo does-not-exist?
does-not-exist?
Run Code Online (Sandbox Code Playgroud)

您可以通过打开来使bash行为zshnomatch选项集相似failglob

$ shopt -s failglob
$ echo does-not-exist?
bash: no match: does-not-exist?
Run Code Online (Sandbox Code Playgroud)

更一般地,您可以禁用 shell 文件名生成:

$ set -f
$ : "The command"
$ set +f
Run Code Online (Sandbox Code Playgroud)

(或set -o noglob, set +o noglob)

或者使用一种 shell引用方法来使 shell 处理?和其他模式匹配特殊字符。


zsh还提供了noglob内置命令,它为以下简单命令禁用任何单词中的文件名生成:

$ noglob echo *
*
Run Code Online (Sandbox Code Playgroud)