Ich versuche, ein Skript zu schreiben, das in einem bestimmten Verzeichnis mit vielen Unterverzeichnissen auf einer Ebene ausgeführt wird. Das Skript cd in jedes der Unterverzeichnisse, führt einen Befehl für die Dateien im Verzeichnis aus und cd out, um mit dem nächsten Verzeichnis fortzufahren. Wie geht das am besten?
shell-script
Etwas Jones
quelle
quelle
youtube-dl
.Antworten:
quelle
for d in ./*/
Startet eine Schleife, in der jedes Element./*/
(in diesem Fall eine Liste von Dateien / Ordnern) in einer Variablen gespeichert wird$d
.do (cd "$d" && somecommand);
startet den Körper der Schleife. Innerhalb des Körpers startet es eine Subshell und führt die Befehlecd
und aussomecommand
. Da es sich um eine untergeordnete Shell handelt, behält die übergeordnete Shell (die Shell, von der aus Sie diesen Befehl ausführen) das CWD und andere Umgebungsvariablen bei.done
schließt einfach den Schleifenkörper.for d in ./*/ ; do (cd "$d" && ls); done
wird nicht funktionieren. aberfor d in ./*/ ; do (cd "$d" && for d in ./*/ ; do (cd "$d" && ls); done ); done
wird funktionieren. -verwendet ls als Befehl in diesem Beispiel.-bash: cd: ./*/: No such file or directory
Der beste Weg ist, überhaupt nicht zu verwenden
cd
:execdir
ist wieexec
, aber das Arbeitsverzeichnis ist anders:Es ist kein POSIX.
quelle
find
führt diese Befehle aus, sodass keine Aliase erkannt werden. Was istmd
und ist das.link
ein Verzeichnis?bash
:find . -type f -iname '*.link' -execdir ${BASH_ALIASES[md]} -i {} \;
Sie brauchen nicht zu tuncat
mitwget
, was einen hat-i
in einer URL - Flag aus einer Datei zu lesen. Auch dies unterscheidet sich ein wenig von Ihrer ursprünglichen Frage (da Sie anscheinend nur an den genannten Dateien interessiert sind.link
und nicht an anderen Dateien, die möglicherweise vorhanden sind).Der obige Befehl muss keine Subshells ausführen - er protokolliert lediglich den Fortschritt in der aktuellen Shell, indem er
$OLDPWD
und abwechselt$PWD
. Wenn Siecd -
die Shell austauschen, ändert sie im Grunde genommen den Wert dieser beiden Variablen, während sie die Verzeichnisse wechselt. Es druckt auch den Namen für jedes Verzeichnis, wie es dort zu stderr arbeitet.Ich habe es mir nur ein zweites Mal angesehen und festgestellt, dass ich mit der Fehlerbehandlung besser umgehen kann. Es überspringt ein Verzeichnis, in das es nicht kann,
cd
undcd
gibt eine Meldung aus, warum stderr ausgeführt werden muss, und es weistbreak
einen Exit-Code ungleich Null auf, wenn diecommand
Ausführung nicht erfolgreich ist oder wenn diecommand
Möglichkeit, in das ursprüngliche Verzeichnis zurückzukehren, auf irgendeine Weise beeinträchtigt wird -$OLDPWD
. In diesem Fall wird auch eincd -
letzter - und der resultierende aktuelle Arbeitsverzeichnisname in stderr geschrieben.quelle
quelle