Por que esse comando ffmpeg funciona no bash e não no zsh?

17

Hoje cheguei em casa do trabalho (execute bash em uma caixa do Ubuntu) e tentei executar algum código na minha caixa de arco local com o meu amado zsh e os comandos estavam falhando?

O comando está abaixo com as informações pessoais e o ip alterado obviamente

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

Funciona perfeitamente no bash, mas quando o executo no zsh, recebo o erro

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

Por que meu amado zsh me traiu?

John Allard
fonte
7
Tente colocar o link rtsp entre aspas simples.
jimmij
1
você é meu herói :) Eu sabia que o zsh não me decepcionaria.
John Allard
1
Tente depois mkdir -p 'rtsp://user:[email protected]:5554/my-media/media.amp-videocodec=h264'e então o bash e o zsh irão falhar. Pelo menos o zsh mostra seu erro aqui.
Stéphane Chazelas 22/03
@cuonglm, eu quis dizer que quando há um arquivo que corresponde ao padrão, o zsh e o bash "falham", pois a glob será expandida. O comportamento do zsh é mais seguro, pois quando não há correspondência, você percebe seu erro.
Stéphane Chazelas 22/03

Respostas:

43

Na sequência:

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

você tem ?nessa string, portanto o shell executará a expansão do nome do caminho nessa string, usando regras de correspondência de padrões .

Em bash, se as failglobopções não foram definidas, o que é o padrão, o padrão com falha será deixado como está:

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

While zshrelatará nenhum erro de correspondência de padrão com o nomatchconjunto de opções, que é o padrão:

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

Você pode zshsuprimir o erro e imprimir o padrão:

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

Você pode se bashcomportar como zshcom o nomatchconjunto de opções ativando failglob:

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

Mais geral, você pode desativar a geração do nome de arquivo do shell:

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

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

ou usando um dos métodos de citação de shell para fazer com que o shell ?e outros padrões correspondam a caracteres especiais literalmente.


zshTambém forneça o noglobbuilt-in, que desabilita a geração do nome do arquivo em qualquer palavra para o seguinte comando simples:

$ noglob echo *
*
cuonglm
fonte
uau, isso é meio embaraçoso de ter perdido, obrigado pela boa resposta.
John Allard
Mas agora isso me faz questionar: como alguém resolveria isso? Usando aspas? Algo mais? Cat excessivamente complicado + sub-conchas? Seria bom se você adicionasse isso à sua resposta, para torná-la um pouco mais geral e ainda muito completa e correta.
Ismael Miguel
Agora que é uma resposta incrível! Eu votei de acordo. A resposta realmente faltava a última parte. Dizia o que estava errado, mas não a solução. Obrigado.
Ismael Miguel
Outra alternativa: no zsh, você pode desativar o globbing apenas para o comando atual, acrescentando noglob-o ao comando. Por exemplo noglob echo *, simplesmente produzirá *.
Wjv 12/04