it-swarm.com.de

CD in alle Verzeichnisse, führen Sie den Befehl für Dateien in diesem Verzeichnis aus und kehren Sie zum vorherigen aktuellen Verzeichnis zurück

Ich versuche, ein Skript zu schreiben, das in einem bestimmten Verzeichnis mit vielen einstufigen Unterverzeichnissen 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. Was ist der beste Weg, dies zu tun?

44
Something Jones
for d in ./*/ ; do (cd "$d" && somecommand); done
96
psusi

Der beste Weg ist, cd überhaupt nicht zu verwenden:

find some/dir -type f -execdir somecommand {} \;

execdir ist wie exec, aber das Arbeitsverzeichnis ist anders:

-execdir command {} [;|+]
  Like   -exec,   but  the  specified  command  is  run  from  the
  subdirectory containing the matched file, which is not  normally
  the  directory  in  which  you  started  find.  This a much more
  secure  method  for  invoking  commands,  as  it   avoids   race
  conditions  during resolution of the paths to the matched files.

Es ist nicht POSIX.

18
muru
cd -P .
for dir in ./*/
do cd -P "$dir" ||continue
   printf %s\\n "$PWD" >&2
   command && cd "$OLDPWD" || 
! break; done || ! cd - >&2

Der obige Befehl muss keine Subshells ausführen - er verfolgt lediglich den Fortschritt in der aktuellen Shell durch Abwechseln von $OLDPWD und $PWD. Wenn du cd - Die Shell tauscht den Wert dieser beiden Variablen grundsätzlich aus, wenn sie Verzeichnisse ändert. Es gibt auch den Namen für jedes Verzeichnis aus, da es dort für stderr funktioniert.

Ich habe es mir nur noch einmal angesehen und beschlossen, mit der Fehlerbehandlung einen besseren Job zu machen. Es wird ein Verzeichnis übersprungen, in das es nicht cd - und cd eine Nachricht darüber drucken kann, warum stderr - und es wird break mit einem Exit-Code ungleich Null, wenn Ihr command wird nicht erfolgreich ausgeführt oder wenn das Ausführen von command die Fähigkeit beeinträchtigt, in Ihr ursprüngliches Verzeichnis zurückzukehren - $OLDPWD. In diesem Fall wird auch ein cd - last - und schreibt den resultierenden aktuellen Arbeitsverzeichnisnamen in stderr.

2
mikeserv
pushd subdir
# do stuff
popd

pushd/popd sind Bash-Buildins, die einen Stapel von Verzeichnissen bereitstellen. Sie können mehrere pushds und dann mehrere popds ausführen und zu Ihrem Ausgangspunkt zurückkehren. Sie können den Stapel auch mit dirs bearbeiten.

Als eingebaute Bash befindet sich die Dokumentation in der Bash-Manpage (man 1 bash und suche (/) für pushd n, um durch die Suchergebnisse zu gelangen) oder verwenden Sie help pushdhelp popdhelp dirs.

2
drewbenn
for D in ./*; do
    if [ -d "$D" ]; then
        cd "$D"
        run_something
        cd ..
    fi
done
1
Kirill