Warum funktioniert der Befehl ffmpeg in bash und nicht in zsh?

17

Heute bin ich von der Arbeit nach Hause gekommen (Bash auf einer Ubuntu-Box ausführen) und habe versucht, mit meinem geliebten zsh Code auf meiner lokalen Arch-Box auszuführen, und die Befehle sind fehlgeschlagen?

Der Befehl ist unten mit den persönlichen Daten und IP offensichtlich geändert

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

Es läuft perfekt in bash, aber wenn ich es in zsh laufen lasse, bekomme ich den Fehler

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

Warum hat mich mein geliebter Zsh betrogen?

John Allard
quelle
7
Versuchen Sie, den rtsp-Link in einfache Anführungszeichen zu setzen.
Jimmy
1
Du bist mein Held :) Ich wusste, dass zsh mich nicht im Stich lassen würde.
John Allard
1
Versuchen Sie es nach mkdir -p 'rtsp://user:[email protected]:5554/my-media/media.amp-videocodec=h264'und dann schlagen sowohl bash als auch zsh fehl. Zumindest zsh zeigt dir hier deinen Fehler.
Stéphane Chazelas
@cuonglm, ich meinte, wenn es eine Datei gibt, die dem Muster entspricht, werden sowohl zsh als auch bash "fehlschlagen", indem der Glob erweitert wird. Das Verhalten von zsh ist insofern vernünftiger, als Sie Ihren Fehler erkennen, wenn es keine Übereinstimmung gibt.
Stéphane Chazelas

Antworten:

43

In Zeichenfolge:

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

Sie haben ?in dieser Zeichenfolge, so dass die Shell Pfadnamenerweiterungen für diese Zeichenfolge unter Verwendung von Mustervergleichsregeln ausführt .

In bash, wenn failglobwurde Optionen nicht gesetzt, was Standard ist, dann scheiterte Muster bleiben , wie sie ist:

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

While zshmeldet keinen Musterübereinstimmungsfehler mit eingestellter nomatchOption. Dies ist die Standardeinstellung:

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

Sie können zshden Fehler unterdrücken und das Muster drucken lassen:

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

Sie können das bashVerhalten wie zshbei nomatchOptionssätzen festlegen, indem Sie Folgendes aktivieren failglob:

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

Im Allgemeinen können Sie die Generierung von Shell-Dateinamen deaktivieren:

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

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

Oder verwenden Sie eine der Shell- Anführungszeichen- Methoden, um die Shell-Leckerchen ?und andere Muster mit Sonderzeichen buchstäblich abzugleichen.


zshnoglobGeben Sie außerdem das integrierte Element an, mit dem die Generierung von Dateinamen in beliebigen Worten für den folgenden einfachen Befehl deaktiviert wird:

$ noglob echo *
*
cuonglm
quelle
oh wow das ist irgendwie peinlich verpasst zu haben, danke für die nette antwort.
John Allard
Aber jetzt frage ich mich: Wie würde jemand das beheben? Mit Anführungszeichen? Etwas anderes? Überkomplizierte Katze + Unterschalen? Es wäre schön, wenn Sie dies zu Ihrer Antwort hinzufügen würden, um sie etwas allgemeiner und dennoch sehr vollständig und korrekt zu gestalten.
Ismael Miguel
Das ist eine großartige Antwort! Ich habe dementsprechend abgestimmt. Der Antwort fehlte wirklich das letzte bisschen. Es sagte, was falsch ist, aber nicht die Lösung. Vielen Dank.
Ismael Miguel
Eine weitere Alternative: In zsh können Sie das Globbing nur für den aktuellen Befehl deaktivieren, indem Sie noglobdem Befehl voranstellen . ZB noglob echo *wird einfach ausgegeben *.
WJV