Skript funktioniert nicht, wenn es extern aufgerufen wird

8

Ich benutze ein einfaches Skript, um .mp3s aus .mp4-Dateien zu erstellen:

#!/bin/bash
for i in *.mp4
do
ffmpeg -i "$i" -ab 128k "${i%mp4}mp3"
done

Das Skript läuft einwandfrei, wenn es vom Desktop ausgeführt oder über das Terminal aufgerufen wird. Wenn das Skript jedoch von einem externen Skript aufgerufen wird, kann es nicht ausgeführt werden und kehrt zurück

"* .mp4: Keine solche Datei oder kein solches Verzeichnis".

Ich vermute, dass das Problem bei der Shell-Erweiterung liegt, kann mich aber nicht darum kümmern, wie ich es in dieser Situation beheben kann.

M. Street
quelle

Antworten:

13

Sie verwenden einen relativen Pfad, in dem Ihr Skript nach den .mp4Dateien im aktuellen Verzeichnis sucht, dh nach dem Verzeichnis, in dem das Skript ausgeführt wird, und wenn Sie feststellen, dass keine solche .mp4Datei vorhanden ist, suchen Sie nach einer Literaldatei *.mp4(vorausgesetzt, nullglob/ failglobist dies nicht set (dies ist die Standardeinstellung), und diese Datei existiert auch nicht, daher die Fehlermeldung *.mp4: No Such File or Directory.

Sie sollten stattdessen den absoluten Pfad verwenden:

for i in /directory/*.mp4; do ...; done

Ersetzen Sie /directory/durch den tatsächlichen Verzeichnispfad. Wenn Sie möchten, können Sie auch den Verzeichnisnamen als erstes Argument verwenden:

for i in "$1"/*.mp4; do ...; done

Sie können hier den absoluten oder relativen Pfad verwenden, aber auch hier ist der absolute Pfad immer die sicherere Option.

Rufen Sie nun das ausführbare Skript wie gewohnt auf:

/path/to/script.sh /directory

Aus dem Skriptverzeichnis:

./script.sh /directory
heemayl
quelle
Danke für die Hilfe. Ich wollte Ihnen gerade sagen, dass ich das bereits erfolglos versucht hatte, aber dann bemerkte ich, dass ich das "H" in "/ home" beim ersten Mal groß geschrieben hatte. Die Übergabe des Pfades als Argument war besonders nützlich. Prost.
M. Street
Wobei "daher die Fehlermeldung" tatsächlich bedeutet: Da die Shell nicht mit *.mp4einer Datei übereinstimmen kann, wird sie als wörtlicher Dateiname betrachtet und versucht, die aufgerufene Datei *.mp4(die ein gültiger Dateiname ist) zu öffnen. Dies schlägt fehl, da Sie keine Datei haben *.mp4im aktuellen Verzeichnis aufgerufen . Jemand könnte denken, dass *.mp4immer auf die Liste der übereinstimmenden Dateinamen erweitert wird, die leer sein könnten (und in diesem Fall würde die forSchleife nichts tun, aber keine Fehler werden ausgelöst), dies ist nicht der Fall: *.mp4erweitert sich immer zu etwas.
Bakuriu
@ Bakuriu Während dies in diesem Fall wahr ist (oder standardmäßig in bash), aber nicht immer; schau dir nullglob/ an failglob.
Heemayl
Wenn ich mich geirrt habe, ist das '*' nur für den Dateinamen gedacht und nicht für die Kombination aus Pfad UND Dateiname. leben und lernen :)
M. Street