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?

157voto

yoctotutor.com Punkte 4961
  1. Ein einfaches Skript zum Testen, ob ein Verzeichnis oder eine Datei vorhanden ist oder nicht:

     if [ -d /home/ram/dir ]   # For file "if [ -f /home/rama/file ]"
     then
         echo "dir present"
     else
         echo "dir not present"
     fi
  2. Ein einfaches Skript, um zu prüfen, ob das Verzeichnis vorhanden ist oder nicht:

     mkdir tempdir   # If you want to check file use touch instead of mkdir
     ret=$?
     if [ "$ret" == "0" ]
     then
         echo "dir present"
     else
         echo "dir not present"
     fi

    Die obigen Skripte prüfen, ob das Verzeichnis vorhanden ist oder nicht

    $? wenn der letzte Befehl erfolgreich war, wird "0" zurückgegeben, ansonsten ein Wert ungleich Null. Angenommen, tempdir bereits vorhanden ist. Dann mkdir tempdir gibt eine Fehlermeldung wie unten:

    mkdir: kann das Verzeichnis 'tempdir' nicht erstellen: Datei existiert

8 Stimmen

Die zweite würde das Verzeichnis erstellen, wenn es noch nicht vorhanden ist. Dann ist es nicht idempotent.

2 Stimmen

. Die 2. scheint gefährlich zu sein. Da sie das Verzeichnis erstellt, ist es nicht einmal mehr wahr, dass das Verzeichnis nicht vorhanden ist.

0 Stimmen

Mkdir erstellt auch nicht den vollständigen Pfad (ohne Parameter), aber das Gegenteil wäre noch gefährlicher, da Sie nicht einmal in der Lage sind, die Änderungen rückgängig zu machen (rm -f), da Sie nicht wissen, welche Verzeichnisse erstellt wurden

147voto

Jorge Barroso Punkte 1788

Um zu prüfen, ob ein Verzeichnis existiert, können Sie ein einfaches if eine solche Struktur:

if [ -d directory/path to a directory ] ; then
# Things to do

else #if needed #also: elif [new condition]
# Things to do
fi

Sie können dies auch in negativer Form tun:

if [ ! -d directory/path to a directory ] ; then
# Things to do when not an existing directory

Nota : Seien Sie vorsichtig. Lassen Sie auf beiden Seiten der Öffnungs- und Schließstreben Leerräume.

Mit der gleichen Syntax können Sie verwenden:

-e: any kind of archive

-f: file

-h: symbolic link

-r: readable file

-w: writable file

-x: executable file

-s: file size greater than zero

0 Stimmen

Inwiefern ist dies besser als die akzeptierte Antwort aus dem Jahr 2008, abgesehen davon, dass sie mit den Dateischaltern vom Thema abweicht?

0 Stimmen

Besser, weil [ ! -d Verzeichnis/Pfad zu einem Verzeichnis ]

111voto

kenorb Punkte 134883

Sie können verwenden test -d (siehe man test ).

-d file Wahr, wenn die Datei existiert und ein Verzeichnis ist.

Zum Beispiel:

test -d "/etc" && echo Exists || echo Does not exist

Anmerkung: Die test Befehl ist gleichbedeutend mit bedingtem Ausdruck [ (siehe: man [ ), so dass es über Shell-Skripte hinweg portabel ist.

[ - Dies ist ein Synonym für die test gebaut, aber das letzte Argument muss ein Literal sein ] , um die Öffnung anzupassen [ .

Mögliche Optionen oder weitere Hilfe finden Sie hier:

  • help [
  • help test
  • man test o man [

62voto

Oder für etwas völlig Unnützes:

[ -d . ] || echo "No"

9 Stimmen

Es wird niemals "Nein" ausgegeben. Das aktuelle Verzeichnis existiert immer, es sei denn, es wird von einem anderen Thread oder auf andere Weise gelöscht.

61voto

Henk Langeveld Punkte 7622

Das ist eine sehr pragmatische Redewendung:

(cd $dir) || return # Is this a directory,
                    # and do we have access?

Normalerweise verpacke ich sie in eine Funktion:

can_use_as_dir() {
    (cd ${1:?pathname expected}) || return
}

Oder:

assert_dir_access() {
    (cd ${1:?pathname expected}) || exit
}

Das Schöne an diesem Ansatz ist, dass ich mir keine gute Fehlermeldung ausdenken muss.

cd gibt mir eine einzeilige Standardmeldung an Standardfehler bereits. Es wird auch mehr Informationen geben, als ich zur Verfügung stellen kann. Durch die Durchführung der cd innerhalb einer Unterschale ( ... ) hat der Befehl keine Auswirkungen auf das aktuelle Verzeichnis des Aufrufers. Wenn das Verzeichnis existiert, sind diese Subshell und die Funktion einfach ein No-op.

Als nächstes folgt das Argument, das wir an cd : ${1:?pathname expected} . Hierbei handelt es sich um eine ausgefeiltere Form der Parametersubstitution, die im Folgenden näher erläutert wird.

Tl;dr: Wenn die an diese Funktion übergebene Zeichenkette leer ist, verlassen wir die Subshell wieder ( ... ) und kehren aus der Funktion mit der angegebenen Fehlermeldung zurück.


Zitiert aus dem ksh93 man-Seite:

${parameter:?word}

Wenn parameter gesetzt ist und nicht Null ist, dann ersetzen Sie seinen Wert; sonst wird gedruckt word und verlassen Sie die Shell (falls nicht interaktiv). Wenn word weggelassen wird, wird eine Standardmeldung gedruckt.

et

Wenn der Doppelpunkt : in den obigen Ausdrücken weggelassen wird, dann wird die Shell nur prüfen, ob der Parameter gesetzt ist oder nicht.

Die Formulierung hier ist eine Besonderheit der Shell-Dokumentation, da word kann sich auf jede sinnvolle Zeichenkette beziehen, einschließlich Leerzeichen.

In diesem speziellen Fall weiß ich, dass die Standardfehlermeldung 1: parameter not set ist nicht ausreichend, also zoome ich auf die Art des Wertes, den wir hier erwarten - die pathname eines Verzeichnisses.

Eine philosophische Anmerkung:

Die Shell ist keine objektorientierte Sprache, daher lautet die Meldung pathname , nicht directory . Auf dieser Ebene würde ich es lieber einfach halten - die Argumente einer Funktion sind nur Zeichenketten.

0 Stimmen

Dies ist mehr als nur eine Überprüfung auf Existenz: Es prüft die Zugänglichkeit auf Benutzerebene. SO Frage stehen für Bestehen nur. Die richtige Antwort lautet also test -d wie @Grundlefleck erklärte.

8 Stimmen

@F.Hauri - Er hat nicht nach mehr gefragt, das ist wahr. Ich habe jedoch festgestellt, dass ich in der Regel mehr wissen muss als das.

0 Stimmen

Und es ist mir nie in den Sinn gekommen, dass kein Test schlüssig sein kann, wenn er nicht als Root läuft. test -d /unreadable/exists scheitert, auch wenn das Argument existiert.

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