Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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: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

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

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

Why has my beloved zsh betrayed me?

share|improve this question
7  
Try to put rtsp link into single quotes. – jimmij Mar 22 at 6:10
1  
you're my hero :) I knew zsh wouldn't let me down. – John Allard Mar 22 at 6:16
1  
Try after mkdir -p 'rtsp://user:pass@my.webserver.org:5554/my-media/media.amp-videocodec=h264' and then both bash and zsh will fail you. At least zsh shows you your mistake here. – Stéphane Chazelas Mar 22 at 7:02
    
@cuonglm, I meant that when there's a file matching the pattern, both zsh and bash will "fail" in that the glob will be expanded. zsh's behaviour is saner in that when there's no match, it makes you realise your mistake. – Stéphane Chazelas Mar 22 at 9:08
up vote 42 down vote accepted

In string:

rtsp://user:pass@my.webserver.org: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 *
*
share|improve this answer
    
oh wow that's kind of embarrassing to have missed, thanks for the nice reply. – John Allard Mar 22 at 7: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 at 9: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 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 at 8:23
    
@wjv: Thanks, added to the answer. – cuonglm Apr 12 at 8:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.