So laden Sie Ihre Bash-Workflows mit GNU parallel auf

GNU parallelist ein Befehlszeilenprogramm zum parallelen Ausführen von Jobs.

parallelist fantastisch und gehört in die Toolbox eines jeden Programmierers. Aber ich fand die Dokumente zunächst etwas überwältigend. Glücklicherweise können Sie parallelmit nur wenigen grundlegenden Befehlen anfangen, nützlich zu sein .

Warum ist das parallelso nützlich?

Vergleichen wir die sequentielle und parallele Ausführung derselben rechenintensiven Aufgabe.

Stellen Sie sich vor, Sie haben einen Ordner mit WAV-Audiodateien, die in .flac konvertiert werden sollen:

Dies sind ziemlich große Dateien, jede ist mindestens ein Gigabyte.

Wir werden ein anderes großartiges Befehlszeilen-Tool verwenden, ffmpeg, um die Dateien zu konvertieren. Folgendes müssen wir für jede Datei ausführen.

ffmpeg -i audio1.wav audio1.flac

Schreiben wir ein Skript, um jedes nacheinander zu konvertieren:

# convert.sh ffmpeg -i audio1.wav audio1.flac ffmpeg -i audio2.wav audio2.flac ffmpeg -i audio3.wav audio3.flac ffmpeg -i audio4.wav audio4.flac ffmpeg -i audio5.wav audio5.flac

Wir können die Ausführung eines Jobs zeitlich festlegen, indem wir timebeim Aufrufen des Skripts vom Terminal aus voranstellen . timedruckt die während der Ausführung verstrichene Echtzeit.

time ./convert.sh

Unser Drehbuch ist in etwas mehr als einer Minute fertig.

Nicht schlecht. Aber jetzt lass es uns parallel laufen!

Wir müssen nichts an unserem Skript ändern. Mit der -aFlagge können wir unser Skript direkt in leiten parallel. parallelführt jede Zeile als separaten Befehl aus.

parallel -a ./convert.sh

Mit parallellief unsere Umwandlung in etwas mehr als die Hälfte der Zeit. Nett!

Mit nur fünf Dateien ist dieser Unterschied keine so große Sache. Mit größeren Listen und längeren Aufgaben können wir jedoch viel Zeit sparen parallel.

Ich bin auf paralleldie Arbeit mit einer Datenverarbeitungsaufgabe gestoßen, die bei sequentieller Ausführung wahrscheinlich eine Stunde oder länger ausgeführt hätte. Mit paralleldauerte es nur ein paar Minuten.

parallelDie Stromversorgung hängt auch von Ihrem Computer ab. Der Intel i7 meines MacBook Pro verfügt nur über 4 Kerne. Selbst diese kleine Aufgabe brachte sie alle an ihre Grenzen:

Leistungsstärkere Computer verfügen möglicherweise über Prozessoren mit 8, 16 oder sogar 32 Kernen, die durch Parallelisierung Ihrer Jobs eine enorme Zeitersparnis bieten.

Nützlich sein mit parallel

Der andere große Vorteil parallelist die Kürze und Einfachheit. Beginnen wir mit einem fiesen Python-Skript und konvertieren es in einen sauberen Aufruf von parallel.

Hier ist ein Python-Skript, um unsere Audiodateikonvertierung durchzuführen:

import subprocess path = Path.home()/'my-data-here' for audio_file in list(path.glob('*.wav')): cmd = ['ffmpeg', '-i', str(audio_file), f'{audio_file.name.split(".")[0]}.flac'] subprocess.run(cmd, stdout=subprocess.PIPE)

Huch! Das ist eigentlich eine Menge Code, über den man nachdenken muss, um nur einige Dateien zu konvertieren. (Die Ausführung dauert ca. 1,2 Minuten).

Lassen Sie uns unseren Python in konvertieren parallel.

Aufruf eines Skripts mit parallel -a

parallel -a your-script-here.sh ist der nette Einzeiler, den wir oben verwendet haben, um unser Bash-Skript zu pfeifen.

Dies ist großartig, erfordert jedoch, dass Sie das Bash-Skript schreiben, das Sie ausführen möchten. In unserem Beispiel haben wir immer noch jeden einzelnen Anruf an ffmpegin geschrieben convert.sh.

Pipes und String Interpolation mit parallel

Zum Glück parallelgibt uns eine Möglichkeit, convert.shvollständig zu löschen .

Hier ist alles, was wir ausführen müssen, um unsere Konvertierung durchzuführen:

ls *.wav | parallel ffmpeg -i {} {.}.flac

Lassen Sie uns das aufschlüsseln.

Wir erhalten eine Liste aller WAV-Dateien in unserem Verzeichnis mit ls *.wav. Dann leiten wir |diese Liste an parallel.

Parallel bietet einige nützliche Möglichkeiten für die String-Interpolation, sodass unsere Dateipfade korrekt eingegeben werden.

Die erste ist {}, die parallelautomatisch durch eine Zeile aus unserer Eingabe ersetzt wird.

Der zweite Operator ist {.}, der eine Zeile eingibt, wobei jedoch alle Dateierweiterungen entfernt werden.

Wenn wir den Befehl erweitern würden, der parallelfür unsere erste Eingabezeile ausgeführt wird, würden wir sehen ...

ffmpeg -i audio1.wav audio1.flac

Argumente mit Parallel

Wie sich herausstellt, müssen wir nicht einmal abpfeifen ls, um unsere Aufgabe zu erfüllen. Wir können noch einfacher gehen:

parallel ffmpeg -i {} {.}.flac ::: *.wav

parallelNach dem Befehl übergebene Argumente, die durch getrennt sind :::. In diesem Fall lautet unser Argument *.wav, das die Liste aller WAV-Dateien in unserem Verzeichnis bereitstellt. Diese Dateien werden zur Eingabe für unseren blitzschnellen parallelJob.

Fun fact: parallel was built by Ole Tange and published in 2011. According to him, you can use the tool for research without citing the source paper for the modest fee of 10,000 euros!

Thanks for reading!