4462 Stimmen

Wie kann ich prüfen, ob ein Verzeichnis in einem Bash-Shell-Skript existiert?

Mit welchem Befehl kann man in einem Bash-Shell-Skript prüfen, ob ein Verzeichnis existiert oder nicht?

6007voto

Grundlefleck Punkte 118989

Um zu prüfen, ob ein Verzeichnis in einem Shell-Skript existiert, können Sie Folgendes verwenden:

if [ -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY exists.
fi

Oder um zu prüfen, ob ein Verzeichnis nicht existiert:

if [ ! -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY doesn't exist.
fi

Da jedoch Jon Ericson weist darauf hin, dass nachfolgende Befehle möglicherweise nicht wie vorgesehen funktionieren, wenn Sie nicht berücksichtigen, dass ein symbolischer Link auf ein Verzeichnis diese Prüfung ebenfalls besteht. Wenn Sie z.B. dies ausführen:

ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then 
  rmdir "$SYMLINK" 
fi

Die Fehlermeldung wird angezeigt:

rmdir: failed to remove `symlink': Not a directory

Daher müssen symbolische Links möglicherweise anders behandelt werden, wenn nachfolgende Befehle Verzeichnisse erwarten:

if [ -d "$LINK_OR_DIR" ]; then 
  if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here.
    rm "$LINK_OR_DIR"
  else
    # It's a directory!
    # Directory command goes here.
    rmdir "$LINK_OR_DIR"
  fi
fi

Achten Sie besonders auf die doppelten Anführungszeichen, in die die Variablen eingeschlossen sind. Der Grund dafür wird von 8jean erklärt in einer anderen Antwort .

Wenn die Variablen Leerzeichen oder andere ungewöhnliche Zeichen enthalten, wird das Skript wahrscheinlich fehlschlagen.

43 Stimmen

Wenn Sie mit den GNU-Werkzeugen auf Nummer sicher gehen wollen, sollten Sie die -- wird dringend empfohlen (End-of-Options-Marker). Wenn Ihre Variable sonst etwas enthält, das wie eine Option aussieht, schlägt das Skript genauso fehl wie bei Leerzeichen.

4 Stimmen

Für moderne Versionen von bash, ksh, etc. [...] ist ein eingebautes

98 Stimmen

Eines sollten Sie bedenken: [ ! -d "$DIRECTORY" ] ist entweder wahr, wenn $DIRECTORY nicht existiert, oder wenn hace existiert, aber kein Verzeichnis ist. Betrachten Sie etwas wie if [ ! -d "$DIRECTORY" ] ; then mkdir "$DIRECTORY" ; fi Dies wird fehlschlagen, wenn "$DIRECTORY" ist eine Datei. (Natürlich sollten Sie prüfen, ob mkdir Es gibt eine Reihe von Gründen, warum sie scheitern kann.)

624voto

8jean Punkte 8442

Denken Sie daran, Variablen immer in Anführungszeichen zu setzen, wenn Sie in einem Bash-Skript auf sie verweisen. Heutzutage wachsen Kinder mit der Vorstellung auf, dass sie Leerzeichen und viele andere lustige Zeichen in ihren Verzeichnisnamen haben können. (Leerzeichen! Zu meiner Zeit hatten wir keine ausgefallenen Leerzeichen! ;))

Eines Tages wird eines dieser Kinder Ihr Skript mit $DIRECTORY eingestellt auf "My M0viez" und Ihr Skript wird explodieren. Das wollen Sie nicht. Verwenden Sie also dies.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi

22 Stimmen

Ein weiterer Grund, doppelte Anführungszeichen zu verwenden, ist der Fall, dass $DIRECTORY aus irgendeinem Grund nicht gesetzt ist.

6 Stimmen

"Variablen in einem Bash-Skript immer in doppelte Anführungszeichen einschließen". Für Bash technisch nicht notwendig, wenn [[...]] verwendet wird; siehe tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS (Hinweis: keine Worttrennung): "Zwischen [[ und ]] findet keine Dateinamenexpansion oder Worttrennung statt, aber es gibt eine Parameterexpansion und Befehlssubstitution."

4 Stimmen

Verzeichnisse unter Unix/Linux sollten keine Whitespaces haben, und Skripte sollten nicht daran angepasst werden. Es ist schlimm genug, dass Windows dies unterstützt, mit allen Konsequenzen für die Windows-Skripterstellung, aber bitte, um Himmels willen, kein Grund, unnötige Anforderungen einzuführen.

263voto

Jon Ericson Punkte 20031

Beachten Sie die -d Test kann einige überraschende Ergebnisse liefern:

$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory

Abgelegt unter: "Wann ist ein Verzeichnis kein Verzeichnis?" Die Antwort: "Wenn es ein Symlink auf ein Verzeichnis ist." Ein etwas gründlicherer Test:

if [ -d t ]; then 
   if [ -L t ]; then 
      rm t
   else 
      rmdir t
   fi
fi

Weitere Informationen finden Sie im Bash-Handbuch unter Bash bedingte Ausdrücke und die [[ eingebautes Kommando](https://www.gnu.org/software/bash/manual/bash.html#index-_005b) und die [[[ zusammengesetzter Befehl](https://www.gnu.org/software/bash/manual/bash.html#index-_005b_005b) .

15 Stimmen

Oder, unter der Annahme, dass nur Verzeichnisse bearbeitet werden müssen (und Links ignoriert werden können) => if [ -d tmpdir -a ! -L tmpdir ]; then echo "is directory"; rmdir tmpdir; fi ... oder für einen Befehl, der sowohl für Links als auch für Verzeichnisse funktioniert: rm -r tmpdir

252voto

yukondude Punkte 23093

Ich finde die Doppelklammer Version von test macht das Schreiben von Logiktests natürlicher:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi

0 Stimmen

Für if [[ -d "$TARFILE" ]] Ich erhalte [[: nicht gefunden

19 Stimmen

@TheVillageIdiot und @Hedgehog, verwenden Sie die Bash-Shell? Die doppelte Klammer wird nicht universell unterstützt. Hier ist eine SO-Antwort zu diesem Punkt: stackoverflow.com/questions/669452/

9 Stimmen

Und in Busybox ash mit Standardkompilierungsoptionen [[ ]] wird zwar unterstützt, bietet aber eigentlich keine andere Funktionalität als [ ] . Wenn Sie Wert auf Tragbarkeit legen, sollten Sie bei [ ] und verwenden Sie die erforderlichen Umgehungslösungen.

227voto

elmarco Punkte 29466

Kürzere Form:

# if $DIR is a directory, then print yes
[ -d "$DIR" ] && echo "Yes"

11 Stimmen

Funktioniert das so? if $dir is a dir, then echo "yes" ? Eine kleine Erklärung wäre hilfreich :)

8 Stimmen

cmd && other ist eine gängige Abkürzung für if cmd; then other; fi -- dies funktioniert mit den meisten Programmiersprachen, die boolesche Logik unterstützen, und ist bekannt als Kurzschlussauswertung .

8 Stimmen

Das Verhalten ist nicht dasselbe unter set -e (das ist ein Bewährte Verfahren der Shell-Programmierung ).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X