Warum funktioniert dieses Bash-Skript nicht als Automator-Dienst?

Ich weiß sehr wenig über Bash-Scripting oder Terminal-Befehle, das ist alles sehr neu für mich, also bitte haben Sie Geduld mit mir.


Originalskript

Ich möchte ein Skript, das ich auf littlefield.info gefunden habe , als Automator-Dienst verwenden. Dies ist das Originalskript:

for file in *.flv *.mov *.mp4
  do mediainfo "--Inform=Video;%Duration%" $file
done | awk '{total+=$0}END{total=total/1000}END{print strftime("%H:%M:%S",total,1)}'

Vom Ersteller erklärt:

  1. Durchlaufen Sie jede Videodatei in einem Ordner,
  2. Übergeben Sie es an das Programm mediainfo, um die Dauer in Millisekunden zu extrahieren,
  3. Übergeben Sie dieses Ergebnis an das awk-Programm, um alle Zahlen zu addieren, um uns eine Gesamtsumme zu geben,
  4. Übergeben Sie das erneut an awk, um diese Zahl durch 1000 zu teilen, um die Anzahl der Sekunden zu erhalten.
  5. Übergeben Sie das an die Funktion strftime, um das Ergebnis im Format Stunden:Minuten:Sekunden anzuzeigen.

Geändertes Skript

Ich habe die mediainfo- CLI installiert und angefangen zu experimentieren. Anscheinend strftimeist es auf dem Mac nicht verfügbar, also musste ich nach einem anderen Weg suchen, wie ich die Sekunden in eine lesbare Ausgabe umwandeln kann. Ich habe das folgende Skript zusammengeschustert (wahrscheinlich schrecklich ineffizient, aber hey ... es funktioniert):

# the cd is needed for automator
cd "$1"

i=$(for file in *.flv *.mov *.mp4
        do mediainfo "--Inform=Video;%Duration%" $file
    done | awk '{total+=$0}END{print total}')

((i/=1000, sec=i%60, i/=60, min=i%60, hrs=i/60))
timestamp=$(printf "%dh%02dm%02ds" $hrs $min $sec)
echo -e "Total duration of video files in this folder:\n\n$timestamp" > _total_duration.txt

Im Terminal funktioniert es einwandfrei. Wenn Sie es jedoch als Dienst von Finder ausführen, erhalten Sie die folgende Ausgabe:

Gesamtdauer der Videodateien in diesem Ordner:

0h00m00s

awk Variablenproblem

Die Dauer sollte nicht 0 sein. Ich habe mit der Fehlerbehebung begonnen und das Skript auf Folgendes reduziert:

for file in *.flv *.mov *.mp4
    do mediainfo "--Inform=Video;%Duration%" $file
done | awk '{total+=$0}END{print total}'  > "test_file_awk.txt"

Es scheint ein Problem mit der Variable totalin AWK zu geben. Es gibt nichts aus, wenn es vom Finder ausgeführt wird, funktioniert aber vom Terminal aus korrekt.

Habt ihr eine Ahnung, was ich falsch mache?

Antworten (1)

Beginnen wir mit einem kleinen Beispiel.

Starten Sie Automator und erstellen Sie einen Dienst mit einem einzigen „Run Shell Script“-Schritt.

Stellen Sie es so ein, dass Ordner als Eingabe vom Finder verwendet werden

Übergeben Sie die Eingabe als Argumente. Shell ist /bin/bash

Bash-Code:

cd "$@"

for file in *.mov *.flk *.mp4
    do
    ls -1 "$file" >> ~/Desktop/test_file_awk.txt
done

Was dies tut, nimmt das Verzeichnis, das Sie als "$@" übergeben, und geht hinein und führt dann den Befehl für alle Dateien in diesem Verzeichnis aus.

"$@" steht zum Schutz vor Leerzeichen in Anführungszeichen, ebenso wie "$file"

Sie können dies also auf Ihr Setup replizieren:

cd "$@"
i=$(for file in {*.flv,*.mov,*.mp4,*.m4v}
    do 
    /usr/local/bin/mediainfo "--Inform=Video;%Duration%" "$file"
done | awk '{total+=$0}END{print total}')

((i/=1000, sec=i%60, i/=60, min=i%60, hrs=i/60))
timestamp=$(printf "%dh%02dm%02ds" $hrs $min $sec)
echo -e "Total duration of video files in this folder:\n\n$timestamp" > _total_duration.txt

Persönlich würde ich die Ausgabe so ändern:

> ~/Desktop/"$@"_total_duration.txt

Damit die Daten auf Ihrem Desktop in einer Datei landen, die nach dem Ordner benannt ist, aber ich habe viele Medienverzeichnisse und ich möchte keine txt-Dateien darin.

Danke für die Antwort! Aber ich bekomme immer noch 0h00m00s als Ausgabe. Die Variable scheint leeri zu sein . Wenn ich dies nach dem awk-Teil ausführe: bekomme ich dies als Ausgabe: "This is i: " echo "This is i: $(i)" > _total_duration.txt
Probieren Sie es jetzt aus, funktioniert bei mir.
Eindrucksvoll! Vielen Dank. Warum müssen Sie /usr/local/bin/vor dem mediainfoBefehl in Automator schreiben und nicht in Terminal?
Eigentlich nicht sicher, ob dies vollständig erforderlich ist, aber einige Automatisierungsumgebungen (insbesondere cron, autosys) werden nicht mit einer vollständigen Benutzerumgebung ausgeführt und erfordern entweder das Laden dieser Umgebung oder vollständige Pfade. Ich habe es sicherheitshalber beim Debuggen eingefügt.
Nun, das Hinzufügen des vollständigen Pfads hat den Zweck erfüllt. Also vielen Dank :)
Ich verwende MacOS 10.15 und das Zitat cd "$@"funktioniert nicht!. Aber cd $@funktioniert.