Wie kann ich überprüfen, ob ein Verzeichnis in einem Bash-Shell-Skript vorhanden ist?

3722

Mit welchem ​​Befehl kann überprüft werden, ob in einem Bash-Shell-Skript ein Verzeichnis vorhanden ist oder nicht?

Grundlefleck
quelle

Antworten:

5149

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

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

Oder um zu überprüfen, ob kein Verzeichnis vorhanden ist:

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

Wie Jon Ericson jedoch betont, funktionieren nachfolgende Befehle möglicherweise nicht wie beabsichtigt, wenn Sie nicht berücksichtigen, dass eine symbolische Verknüpfung zu einem Verzeichnis diese Prüfung ebenfalls besteht. ZB laufen lassen:

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

Wird die Fehlermeldung erzeugen:

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

Beachten Sie insbesondere die doppelten Anführungszeichen, mit denen die Variablen umbrochen werden. Der Grund dafür wird von 8jean in einer anderen Antwort erklärt .

Wenn die Variablen Leerzeichen oder andere ungewöhnliche Zeichen enthalten, schlägt das Skript wahrscheinlich fehl.

Grundlefleck
quelle
29
Wenn Sie mit den GNU-Tools auf Nummer sicher gehen möchten, wird die Verwendung von --dringend empfohlen (End-of-Options-Marker). Andernfalls schlägt das Skript wie bei Leerzeichen fehl, wenn Ihre Variable etwas enthält, das wie eine Option aussieht.
Marc Mutz - mmutz
2
Für moderne Versionen von bash, ksh etc. [...] ist ein builtin
fpmurphy
79
Eine Sache, die Sie beachten sollten: [ ! -d "$DIRECTORY" ]Wird wahr sein, wenn $DIRECTORYsie nicht existiert oder wenn sie existiert, aber kein Verzeichnis ist. Betrachten Sie etwas wie if [ ! -d "$DIRECTORY" ] ; then mkdir "$DIRECTORY" ; fi; Dies schlägt fehl, wenn "$DIRECTORY"es sich um eine Datei handelt. (Natürlich sollten Sie prüfen, ob mkdires trotzdem gelungen ist; es gibt eine Reihe von Gründen, warum dies fehlschlagen kann.)
Keith Thompson
5
Es kann erwähnenswert sein, dass sich die Situation bereits aufgrund anderer Prozesse geändert haben kann, sobald die Prüfung durchgeführt wurde. In vielen Fällen ist es besser, einfach das Verzeichnis zu erstellen oder zu verwenden und auf einen Fehler zu reagieren.
Alfe
12
Anstatt sowohl nach dem Verzeichnis ( -d) als auch nach dem Symlink ( -L) zu testen , ist es einfacher, einfach einen Schrägstrich an die Variable anzuhängen, wie z if [ -d "${THING:+$THING/}" ]. Ein Verzeichnis hat nichts gegen den zusätzlichen Schrägstrich. Eine Datei wird als falsch ausgewertet. Leer bleibt leer, also falsch. Und ein Symlink wird zu seinem Ziel aufgelöst. Natürlich hängt es von Ihrem Ziel ab. Wenn Sie wollen , gehen Sie dort, das ist in Ordnung. Wenn Sie es löschen möchten , ist der Code in dieser Antwort besser.
Ghoti
531

Denken Sie daran, Variablen immer in doppelte Anführungszeichen zu setzen, wenn Sie in einem Bash-Skript auf sie verweisen. Kinder wachsen heutzutage mit der Idee auf, dass sie Leerzeichen und viele andere lustige Charaktere in ihren Verzeichnisnamen haben können. (Räume! Damals hatten wir keine ausgefallenen Räume !;))

Eines Tages wird eines dieser Kinder Ihr Skript mit $DIRECTORYset to ausführen "My M0viez"und Ihr Skript wird explodieren. Das willst du nicht. Also benutze das.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi
8jean
quelle
9
Ein weiterer Grund für die Verwendung von doppelten Anführungszeichen ist der Fall, dass $ DIRECTORY aus irgendeinem Grund nicht festgelegt ist.
Jon Ericson
2
"Variablen immer in doppelte Anführungszeichen setzen ... in ein Bash-Skript." Für Bash technisch nicht notwendig bei Verwendung von [[...]]; Siehe tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS (Hinweis: Keine Wortaufteilung ): "Zwischen [[und]] findet keine Dateinamenerweiterung oder Wortaufteilung statt, aber es gibt Parametererweiterung und Befehlssubstitution."
Michael
2
Verzeichnisse unter Unix / Linux sollten keine Leerzeichen haben, und anschließend sollten Skripte nicht daran angepasst werden. Es ist schon schlimm genug, dass Windows es unterstützt, mit allen Konsequenzen für Windows-Skripte, aber bitte, aus Liebe zu allem, müssen Sie keine unnötigen Anforderungen einführen.
TVCa
18
@tvCa Ich finde, dass Benutzer es im Allgemeinen vorziehen, mehr Flexibilität in ihren Verzeichnisnamen zu erhalten, anstatt gezwungen zu sein, Entwicklern die Arbeit zu erleichtern. (Tatsächlich empfinde ich beim Umgang mit langen Dateinamen solche ohne Leerzeichen als schmerzhaft, da dies das Umbrechen von Wörtern verhindert, obwohl ich selbst in der Vergangenheit darunter gelitten habe, Pfade mit Leerzeichen in Skripten und Programmen nicht zu berücksichtigen.)
JAB
2
Ha. Leerzeichen sind nur Zeichen, die normalerweise keine Glyphen haben. Wie auch immer, Sie können ihnen mit einem Backslash entkommen.
Uchuugaka
228

Beachten Sie, dass der -d- Test einige überraschende Ergebnisse liefern kann:

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

Datei unter: "Wann ist ein Verzeichnis kein Verzeichnis?" Die Antwort: "Wenn es sich um einen Symlink zu einem Verzeichnis handelt." 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 zu Bash-Bedingungsausdrücken sowie im [eingebauten Befehl und im [[zusammengesetzten Befehl .

Jon Ericson
quelle
12
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
Michael
218

Ich finde, dass die Doppelklammerversion von testdas Schreiben von Logiktests natürlicher macht:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi
Yukondude
quelle
denn if [[ -d "$TARFILE" ]]ich bekomme [[: nicht gefunden
TheVillageIdiot
15
@TheVillageIdiot und @Hedgehog, verwenden Sie Bash Shell? Die doppelte Halterung wird nicht allgemein unterstützt. Hier ist eine SO-Antwort zu diesem Punkt: stackoverflow.com/questions/669452/…
yukondude
6
Und in Busybox wird Asche mit Standard-Kompilierungsoptionen [[ ]]unterstützt, bietet aber tatsächlich keine andere Funktionalität als [ ]. Wenn die Portabilität ein Problem darstellt, halten Sie sich an [ ]die erforderlichen Problemumgehungen und verwenden Sie diese.
Dubiousjim
6
... wenn Bash-Konstrukte in einem Shell-Skript verwendet werden, sollte die erste Zeile des Skripts lauten: #! / bin / bash (und nicht #! / bin / sh, ksh usw.)
michael
Wenn Sie in Bash doppelte eckige Klammern verwenden, müssen Sie die Variablen nicht in Anführungszeichen setzen.
Hubert Grzeskowiak
157

Kürzere Form:

[ -d "$DIR" ] && echo "Yes"
Elmarco
quelle
6
Funktioniert das so : if $dir is a dir, then echo "yes"? Ein bisschen Erklärung würde helfen :)
Martijn
5
cmd && otherist eine gebräuchliche Abkürzung für if cmd; then other; fi- dies funktioniert mit den meisten Programmiersprachen, die die Boolesche Logik unterstützen, und wird als Kurzschlussauswertung bezeichnet .
Tripleee
1
Das Verhalten ist nicht dasselbe unter set -e(dies ist eine bewährte Methode für die Shell-Programmierung ).
Dolmen
1
@dolmen the [ -d "$DIR" ]wird überprüft (gefolgt von && echo Yes), daher glaube ich, set -edass es keinen Unterschied zum Skriptverhalten macht (dh wenn der Test fehlschlägt, wird das Skript normal fortgesetzt).
Zot
132

Um zu überprüfen, ob ein Verzeichnis vorhanden ist, können Sie eine einfache ifStruktur wie die folgende verwenden:

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 es auch negativ machen:

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

Hinweis : Seien Sie vorsichtig. Lassen Sie auf beiden Seiten der öffnenden und schließenden Klammern leere Stellen.

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
Jorge Barroso
quelle
Wie ist dies besser als die akzeptierte Antwort aus dem Jahr 2008, abgesehen davon, dass die Dateischalter nicht zum Thema gehören?
Dan Dascalescu
besser wegen [! -d Verzeichnis / Pfad zu einem Verzeichnis]
user1855805
108
  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 überprü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 ist, wird "0" zurückgegeben, andernfalls ein Wert ungleich Null. Angenommen, es tempdirist bereits vorhanden. Dann mkdir tempdirwird ein Fehler wie folgt ausgegeben:

    mkdir: Verzeichnis 'tempdir' kann nicht erstellt werden: Datei existiert

yoctotutor.com
quelle
4
Der zweite würde das Verzeichnis erstellen, wenn es zuerst nicht existierte. Dann ist es nicht idempotent.
Shihe Zhang
👆👆👆. Der zweite scheint gefährlich. Da das Verzeichnis erstellt wird, ist es nicht einmal mehr wahr, dass das Verzeichnis nicht vorhanden ist.
Chris
92

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

-d file True, wenn die Datei vorhanden ist und ein Verzeichnis ist.

Zum Beispiel:

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

Hinweis: Der testBefehl entspricht dem bedingten Ausdruck [(siehe :) man [, ist also für Shell-Skripte portierbar.

[- Dies ist ein Synonym für das testEingebaute, aber das letzte Argument muss wörtlich sein ], um mit der Eröffnung übereinzustimmen [.

Weitere Optionen oder weitere Hilfe finden Sie unter:

  • help [
  • help test
  • man test oder man [
Kenorb
quelle
55

Oder für etwas völlig Nutzloses:

[ -d . ] || echo "No"
etw
quelle
6
Es wird niemals "Nein" gedruckt. Das aktuelle Verzeichnis ist immer vorhanden, es sei denn, es wurde von einem anderen Thread oder auf andere Weise gelöscht.
Jahid
Perfektes Beispiel :) Angesichts der Tatsache, dass einige Antworten im Vergleich zur akzeptierten Antwort "einzigartig" sind
Sergey Sargsyan
4
Warum wurde dies so oft positiv bewertet? Es beantwortet die Frage nicht.
Codeforester
WEIL ES DIE BESTE ANTWORT EVA IST
Karl Morrison
52

Hier ist eine sehr pragmatische Redewendung:

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

Normalerweise verpacke ich es 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 mir keine gute Fehlermeldung einfällt.

cdIch erhalte bereits eine einzeilige Standardnachricht zum Standardfehler . Es wird auch mehr Informationen geben, als ich liefern kann. Durch das Ausführen cdeiner Unterschale wirkt ( ... )sich der Befehl nicht auf das aktuelle Verzeichnis des Aufrufers aus. Wenn das Verzeichnis vorhanden ist, sind diese Unterschale und die Funktion nur ein No-Op.

Als nächstes kommt das Argument, an das wir übergeben cd: ${1:?pathname expected}. Dies ist eine ausführlichere Form der Parametersubstitution, die im Folgenden näher erläutert wird.

Tl; dr: Wenn die an diese Funktion übergebene Zeichenfolge leer ist, verlassen wir die Unterschale erneut ( ... )und kehren mit der angegebenen Fehlermeldung von der Funktion zurück.


Zitat aus der ksh93Manpage:

${parameter:?word}

Wenn parameter gesetzt und nicht null ist, ersetzen Sie seinen Wert. Andernfalls drucken Sie worddie Shell und beenden Sie sie (falls nicht interaktiv). Wenn nicht angegeben, wordwird eine Standardnachricht gedruckt.

und

Wenn der Doppelpunkt :in den obigen Ausdrücken weggelassen wird, prüft die Shell nur, ob ein Parameter festgelegt ist oder nicht.

Die Formulierung hier ist der Shell-Dokumentation eigen, da wordsie sich auf jede vernünftige Zeichenfolge beziehen kann, einschließlich Leerzeichen.

In diesem speziellen Fall weiß ich, dass die Standardfehlermeldung 1: parameter not setnicht ausreicht, daher vergrößere ich den Wertetyp, den wir hier erwarten - den pathnameeines Verzeichnisses.

Eine philosophische Anmerkung:

Die Shell ist keine objektorientierte Sprache, daher heißt es in der Nachricht pathnamenicht directory. Auf dieser Ebene möchte ich es lieber einfach halten - die Argumente für eine Funktion sind nur Zeichenfolgen.

Henk Langeveld
quelle
Dies ist mehr als nur eine Überprüfung der Existenz: Diese Überprüfung der Zugänglichkeit auf Benutzerebene. SO Frage steht nur für Existenz . Die richtige Antwort lautet also test -dwie @Grundlefleck erklärt.
F. Hauri
7
@ F.Hauri - Er hat nicht mehr verlangt, das stimmt. Ich habe jedoch festgestellt, dass ich normalerweise mehr wissen muss.
Henk Langeveld
Und mir ist nie in den Sinn gekommen, dass kein Test schlüssig sein kann, es sei denn, er läuft als Root. test -d /unreadable/existswird fehlschlagen, auch wenn das Argument existiert.
Henk Langeveld
36
if [ -d "$Directory" -a -w "$Directory" ]
then
    #Statements
fi

Der obige Code prüft, ob das Verzeichnis vorhanden und beschreibbar ist.

muralikrishna
quelle
1
-a ist in seiner Wirkung identisch mit -e. Es wurde "veraltet" und von seiner Verwendung wird abgeraten.
CousinCocaine
27
DIRECTORY=/tmp

if [ -d "$DIRECTORY" ]; then
    echo "Exists"
fi

Versuchen Sie es online

Vishal
quelle
erinnere dich spacenach [-> [`` -d . Ich habe einen Fehler wegen fehlenden Platzes bekommen
Raj
4
WIEDER wurde diese Antwort bereits 2008 mit nützlicheren Erklärungen gegeben. Das einzig Neue hier ist der Online-Spielplatz.
Dan Dascalescu
24

Geben Sie diesen Code an der Bash-Eingabeaufforderung ein:

if [ -d "$DIRECTORY" ]; then
    # If true this block of code will execute
fi
Santosh
quelle
WIEDER wurde diese Antwort bereits 2008 gegeben. Was bringt es, sie zu wiederholen?!
Dan Dascalescu
21

Weitere Funktionen mit find

  • Überprüfen Sie die Existenz des Ordners in Unterverzeichnissen:

    found=`find -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where "myDirectory" is.
        # It may contain several lines if there are several folders named "myDirectory".
    fi
  • Überprüfen Sie die Existenz eines oder mehrerer Ordner anhand eines Musters im aktuellen Verzeichnis:

    found=`find -maxdepth 1 -type d -name "my*"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where folders "my*" have been found.
    fi
  • Beide Kombinationen. Im folgenden Beispiel wird die Existenz des Ordners im aktuellen Verzeichnis überprüft:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi
Neil Neyman
quelle
Hallo Niel. Ihre Idee kann nützlich sein, um die Existenz von Verzeichnissen zu überprüfen, abhängig von einem Muster wie : find -maxdepth 1 -type d -name 'pattern'. Stört es Sie, wenn ich in Ihrer Antwort diesen Trick anhänge? Prost;)
Olibre
20

Eigentlich sollten Sie mehrere Tools verwenden, um einen kugelsicheren Ansatz zu erhalten:

DIR_PATH=`readlink -f "${the_stuff_you_test}"` # Get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; Then # Now you're testing
    echo "It's a dir";
fi

Sie müssen sich keine Gedanken über Leerzeichen und Sonderzeichen machen, solange Sie diese verwenden "${}".

Beachten Sie, dass dies [[]]nicht so portabel ist wie [], aber da die meisten Leute mit modernen Versionen von Bash arbeiten (da die meisten Leute schließlich nicht einmal mit der Befehlszeile arbeiten :-p), ist der Nutzen größer als der Ärger.

e-satis
quelle
17

Haben Sie darüber nachgedacht, einfach das zu tun, was Sie wollen, ifanstatt zu schauen, bevor Sie springen?

Wenn Sie also vor dem Betreten überprüfen möchten, ob ein Verzeichnis vorhanden ist, versuchen Sie Folgendes:

if pushd /path/you/want/to/enter; then
    # Commands you want to run in this directory
    popd
fi

Wenn der Pfad, den Sie angeben, pushdvorhanden ist, geben Sie ihn ein und er wird mit beendet 0, was bedeutet, dass der thenTeil der Anweisung ausgeführt wird. Wenn es nicht existiert, passiert nichts (außer einer Ausgabe, die besagt, dass das Verzeichnis nicht existiert, was wahrscheinlich sowieso ein hilfreicher Nebeneffekt beim Debuggen ist).

Es scheint besser als das, was erfordert, dass Sie sich wiederholen:

if [ -d /path/you/want/to/enter ]; then
    pushd /path/you/want/to/enter
    # Commands you want to run in this directory
    popd
fi

Dasselbe funktioniert mit cd, mv, rm, etc ... , wenn man sie auf Dateien versuchen, die nicht existieren, werden sie mit einem Fehler beenden und eine Meldung aus sagen , dass es nicht vorhanden ist , und Ihr thenBlock wird übersprungen. Wenn Sie sie an vorhandenen Dateien ausprobieren, wird der Befehl ausgeführt und mit dem Status " 0Beendet", sodass Ihr thenBlock ausgeführt werden kann.

ArtOfWarfare
quelle
2
pushd ist für mich die eleganteste Art, dies zu tun. Ich wollte es als Antwort
posten
15

Verwenden Sie diesen Code, um mehr als ein Verzeichnis zu überprüfen:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi
Raamesh Keerthi
quelle
Wie können Sie überprüfen, ob es nicht existiert?
Perrohunter
15

Überprüfen Sie, ob das Verzeichnis vorhanden ist, andernfalls erstellen Sie eines:

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
David Okwii
quelle
16
Sie können mkdir -p "$DIRECTORY"für den gleichen Effekt verwenden.
Logan Pickup
15
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

NB: Das Zitieren von Variablen ist eine gute Praxis.

Erläuterung:

  • -d: Überprüfen Sie, ob es sich um ein Verzeichnis handelt
  • -L: Überprüfen Sie, ob es sich um einen symbolischen Link handelt
Jahid
quelle
Eine Erklärung wäre angebracht (durch Bearbeiten Ihrer Antwort , nicht hier in Kommentaren).
Peter Mortensen
13
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"
Juan Carlos Kuri Pinto
quelle
Eine Erklärung wäre angebracht (durch Bearbeiten Ihrer Antwort , nicht hier in Kommentaren).
Peter Mortensen
11

Diese Antwort wurde als Shell-Skript zusammengefasst

Beispiele

$ is_dir ~                           
YES

$ is_dir /tmp                        
YES

$ is_dir ~/bin                       
YES

$ mkdir '/tmp/test me'

$ is_dir '/tmp/test me'
YES

$ is_dir /asdf/asdf                  
NO

# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
  echo "Folder doesnt exist: $DIR";
  exit;
fi

is_dir

function show_help()
{
  IT=$(CAT <<EOF

  usage: DIR
  output: YES or NO, depending on whether or not the directory exists.

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

DIR=$1
if [ -d $DIR ]; then 
   echo "YES";
   exit;
fi
echo "NO";
Brad Parks
quelle
10

Mit der -ePrüfung wird nach Dateien gesucht, einschließlich Verzeichnissen.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi
bailey86
quelle
1
Und beantwortet die Frage des OP nicht richtig - ist es ein Verzeichnis?
Mark Stewart
8

Gemäß Jonathans Kommentar:

Wenn Sie das Verzeichnis erstellen möchten und es noch nicht vorhanden ist, verwenden Sie am einfachsten mkdir -pdas Verzeichnis - und alle fehlenden Verzeichnisse im Pfad - und schlagen nicht fehl, wenn das Verzeichnis bereits vorhanden ist, sodass Sie alles tun können sofort mit:

mkdir -p /some/directory/you/want/to/exist || exit 1
Kenorb
quelle
7
if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

Das ist nicht ganz richtig ...

Wenn Sie in dieses Verzeichnis wechseln möchten, müssen Sie auch über die Ausführungsrechte für das Verzeichnis verfügen. Möglicherweise müssen Sie auch Schreibrechte haben.

Deshalb:

if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
    # ... to go to that directory (even if DIRECTORY is a link)
    cd $DIRECTORY
    pwd
fi

if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
    # ... to go to that directory and write something there (even if DIRECTORY is a link)
    cd $DIRECTORY
    touch foobar
fi
Peter Mortensen
quelle
7

Verwenden Sie das fileProgramm. Da alle Verzeichnisse auch Dateien unter Linux sind, würde die Ausgabe des folgenden Befehls ausreichen:

file $directory_name

Überprüfen einer nicht vorhandenen Datei: file blah

Ausgabe: cannot open 'blah' (No such file or directory)

Überprüfen eines vorhandenen Verzeichnisses: file bluh

Ausgabe: bluh: directory

Sudip Bhandari
quelle
1
Gute Idee, aber schade in beiden Fällen, dass der Befehl file immer 0 Exit-Code zurückgibt. Auch wenn die Datei / das Verzeichnis nicht gefunden werden kann :(.
Hazard89
6

Der lsBefehl in Verbindung mit der -lOption (lange Auflistung) gibt Attributinformationen zu Dateien und Verzeichnissen zurück.
Insbesondere das erste Zeichen der ls -lAusgabe ist normalerweise ein doder ein -(Bindestrich). Im Falle eines ist ddas aufgelistete sicher ein Verzeichnis.

Der folgende Befehl in nur einer Zeile zeigt an, ob die angegebene ISDIRVariable einen Pfad zu einem Verzeichnis enthält oder nicht:

[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
    echo "YES, $ISDIR is a directory." || 
    echo "Sorry, $ISDIR is not a directory"

Praktische Anwendung:

    [claudio@nowhere ~]$ ISDIR="$HOME/Music" 
    [claudio@nowhere ~]$ ls -ld "$ISDIR"
    drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." ||
        echo "Sorry, $ISDIR is not a directory"
    YES, /home/claudio/Music is a directory.

    [claudio@nowhere ~]$ touch "empty file.txt"
    [claudio@nowhere ~]$ ISDIR="$HOME/empty file.txt" 
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." || 
        echo "Sorry, $ISDIR is not a directoy"
    Sorry, /home/claudio/empty file.txt is not a directory
ztank1013
quelle
+1, aber wenn ISDIR überhaupt nicht existiert, erhalten Sie eine Fehlermeldung sowie Ihre Diagnosemeldung.
Ysap
5
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;
Ajmartin
quelle
Eine Erklärung wäre angebracht (durch Bearbeiten Ihrer Antwort , nicht hier in Kommentaren).
Peter Mortensen
5

Wenn Sie überprüfen möchten, ob ein Verzeichnis vorhanden ist, unabhängig davon, ob es sich um ein echtes Verzeichnis oder einen Symlink handelt, verwenden Sie Folgendes:

ls $DIR
if [ $? != 0 ]; then
        echo "Directory $DIR already exists!"
        exit 1;
fi
echo "Directory $DIR does not exist..."

Erläuterung: Der Befehl "ls" gibt den Fehler "ls: / x: Keine solche Datei oder kein solches Verzeichnis" aus, wenn das Verzeichnis oder der Symlink nicht vorhanden ist, und setzt auch den Rückkehrcode, den Sie über "$?" Abrufen können, auf non -null (normalerweise "1"). Stellen Sie sicher, dass Sie den Rückkehrcode direkt nach dem Aufruf von "ls" überprüfen.

derFunk
quelle
3
Alternativ können Sie diese kürzere Version verwenden:if ! ls $DIR 2>/dev/null; then echo "$DIR does not exist!"; fi
derFunk
5

(1)

[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"

(2)

[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"

(3)

[[ -d run_dir  && ! -L run_dir ]] && echo Exists || echo "Not Exists"

Wenn bei einem der oben genannten Ansätze ein Problem festgestellt wird:

Mit dem lsBefehl; In den Fällen, in denen kein Verzeichnis vorhanden ist, wird eine Fehlermeldung angezeigt

[[ `ls -ld SAMPLE_DIR| grep ^d | wc -l` -eq 1 ]] && echo exists || not exists

-ksh: nicht: nicht gefunden [Keine solche Datei oder kein solches Verzeichnis]

Piyush Baijal
quelle
Worauf bezieht sich "oben"? Die drei Befehlszeilen in dieser Antwort oder vorherigen Antworten? (Bitte bearbeiten Sie Ihre Antwort , nicht hier in den Kommentaren. Vielen Dank im Voraus.)
Peter Mortensen
4

Es gibt großartige Lösungen, aber letztendlich schlägt jedes Skript fehl, wenn Sie sich nicht im richtigen Verzeichnis befinden. Also Code wie folgt:

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

wird nur dann erfolgreich ausgeführt, wenn Sie sich zum Zeitpunkt der Ausführung in einem Verzeichnis befinden, in dem sich ein Unterverzeichnis befindet, nach dem Sie suchen.

Ich verstehe die anfängliche Frage wie folgt: um zu überprüfen, ob ein Verzeichnis existiert, unabhängig von der Position des Benutzers im Dateisystem. Die Verwendung des Befehls 'find' könnte also den Trick machen:

dir=" "
echo "Input directory name to search for:"
read dir
find $HOME -name $dir -type d

Diese Lösung ist gut, da sie die Verwendung von Platzhaltern ermöglicht, eine nützliche Funktion bei der Suche nach Dateien / Verzeichnissen. Das einzige Problem ist, dass, wenn das gesuchte Verzeichnis nicht existiert, der Befehl 'find' nichts in die Standardausgabe druckt (keine elegante Lösung für meinen Geschmack) und dennoch einen Null-Exit hat. Vielleicht könnte jemand dies verbessern.

Dromichaeten
quelle
13
Ich wäre beleidigt, wenn ein Programm meine gesamte Festplatte durchsuchen würde, um ein Verzeichnis zu finden, anstatt nur höflich in mein aktuelles Arbeitsverzeichnis zu schauen oder den absoluten Pfad zu verwenden, den ich ihm gebe. Was Sie vorgeschlagen haben, könnte für ein Tool namens benannt sein, locateaber für nichts anderes ...
Sarnold