18

Today I got home from work (run bash on an Ubuntu box) and tried to run some code on my local arch box with my beloved zsh and the commands were failing?

The command is below with the personal info and ip changed obviously

ffmpeg -i rtsp://user:[email protected]:5554/my-media/media.amp?videocodec=h264  -threads 3 -vcodec copy -f segment -segment_time 2 outfiles/cam_out%04d.mp4

It runs perfect in bash, but when I run it in zsh I get the error

zsh: no matches found: rtsp://user:[email protected]:5554/my-media/media.amp?videocodec=h264

Why has my beloved zsh betrayed me?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
John Allard
  • 1,318
  • 1
  • 14
  • 23

1 Answers1

43

In string:

rtsp://user:[email protected]:5554/my-media/media.amp?videocodec=h264

you have ? in that string, so the shell will perform pathname expansion on that string, using pattern matching rules.

In bash, if failglob options was not set, which is default, then failed pattern will be left as-is:

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

While zsh will report no pattern match error with nomatch option set, which is default:

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

You can make zsh suppress the error and print the pattern:

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

You can make bash behave like zsh with nomatch option set, by turning on failglob:

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

More general, you can disable shell filename generation:

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

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

or using one of shell quoting methods to make the shell treats ? and other pattern matching special characters literally.


zsh also provide the noglob builtin, which disable filename generation in any words for the following simple command:

$ noglob echo *
*
cuonglm
  • 150,973
  • 38
  • 327
  • 406
  • oh wow that's kind of embarrassing to have missed, thanks for the nice reply. – John Allard Mar 22 '16 at 07:19
  • But now this makes me question: How would someone fix it? By using quotes? Something else? Overly-complicated cat+subshells? It would be nice if you added this to your answer, to make it a bit more general and still very complete and correct. – Ismael Miguel Mar 22 '16 at 09:44
  • Now THAT is an awesome answer! I've upvoted accordingly. The answer was really lacking the last bit. It told what's wrong but not the fix. Thank you. – Ismael Miguel Mar 22 '16 at 10:02
  • Another alternative: In zsh, you can disable globbing only for the current command by prepending `noglob` to the command. E.g. `noglob echo *` will simply output `*`. – wjv Apr 12 '16 at 08:23