Frage

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

War es hilfreich?

Lösung

Um zu überprüfen, ob ein Verzeichnis in einem Shell-Skript existiert Sie folgende verwenden:

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

oder zu überprüfen, ob ein Verzeichnis existiert nicht:

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

Wie jedoch Jon Ericson weist darauf hin, können nachfolgende Befehle nicht wie vorgesehen funktionieren, wenn Sie nicht die in der Konto, das ein symbolischer Link zu einem Verzeichnis auch diese Prüfung übergeben wird. Z.B. läuft folgendermaßen aus:

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

Wird die Fehlermeldung erzeugen:

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

So symbolische Links können unterschiedlich behandelt werden, wenn nachfolgende Befehle erwarten Verzeichnisse:

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

besondere Kenntnis von den doppelten Anführungszeichen verwendet Nehmen Sie die Variablen wickeln, der Grund hierfür wird durch 8jean in einer anderen Antwort erklärt .

Wenn die Variablen Leerzeichen oder andere Sonderzeichen enthalten wird es wahrscheinlich das Skript fehlschlagen.

Andere Tipps

Denken Sie daran, immer Variablen in doppelten Anführungszeichen wickeln, wenn Referenzierung in ein Bash-Skript. Kinder in diesen Tagen wachsen mit der Idee, dass sie Räume und viele andere lustige Charaktere in ihrer Verzeichnisnamen haben können. (! Spaces zurück in meinen Tagen, wir haben nicht keine Lust Räume haben;))

Einen Tag, eines dieser Kinder wird das Skript mit $DIRECTORY gesetzt läuft "My M0viez" und Ihr Skript wird die Luft sprengen. Sie wollen nicht, dass. Also diese verwenden.

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

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

$ 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 ein symbolischer Link zu einem Verzeichnis.“ Ein etwas gründlicher Test:

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

Sie können mehr Informationen in der Bash Handbuch finden auf bash bedingte Ausdrücke und der [ builtin Befehl und die [[ Verbindung commmand .

finde ich die Doppelbügel Version test Logik macht das Schreiben Tests natürlichere:

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

Kürzere Form:

[ -d "$DIR" ] && echo "Yes"

Um zu überprüfen, ob ein Verzeichnis existiert können Sie einfach, wenn Struktur wie folgt verwendet werden:

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 in negativer

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

Hinweis :. Seien Sie vorsichtig, lassen Sie leere Räume auf beiden Seiten der beiden Öffnungs- und Schließ Klammern

Mit der gleichen Syntax können Sie:

-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 
if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi

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

  

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

Zum Beispiel:

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

Hinweis: Der test Befehl ist der gleiche wie bedingter Ausdruck [ (siehe: man [)., So ist es für Shell-Skripten portable

  

[ -. Dies ist ein Synonym für die test builtin, aber das letzte Argument ist, eine wörtliche ] sein, um die Öffnung [ passen

Für mögliche Optionen oder weitere Hilfe überprüfen:

  • help [
  • help test
  • man test oder man [
  1. Ein einfaches Skript zu testen, ob dir oder 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 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 oben genannte Skripte prüft die dir vorhanden ist oder nicht

    $? wenn der letzte Befehl Sucess es „0“ sonst Wert ungleich Null zurückgibt. suppose tempdir bereits vorhanden ist, dann wird mkdir tempdir Fehler geben wie folgt:

      

    mkdir: kann nicht erstellen Verzeichnis ‚tempdir‘: Die Datei existiert

Oder etwas völlig nutzlos:

[ -d . ] || echo "No"

Hier ist ein sehr pragmatisches Idiom:

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

ich es in der Regel wickeln in einer 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 müssen nicht denken Sie an eine gute Fehlermeldung.

cd gibt mir eine Standard eine Zeile Nachricht bereits nach stderr. Es wird auch mehr Informationen geben, als ich in der Lage sein wird, zu liefern. Durch die Durchführung des cd innerhalb einer Subshell ( ... ), wird der Befehl nicht das aktuelle Verzeichnis des Anrufers beeinflussen. Wenn das Verzeichnis vorhanden ist, dies Sub-Shell und die Funktion ist nur ein No-op.

Als nächstes ist das Argument, das wir cd passieren: ${1:?pathname expected}. Dies ist eine aufwendigere Form von Parametern Substitution, die im Folgenden näher erläutert wird.

Tl; dr: Wenn die Zeichenfolge in diese Funktion übergeben ist leer, wir wieder Austritt aus der Subshell ( ... ) und Rückkehr aus der Funktion mit der angegebenen Fehlermeldung.


von der ksh93 Manpage Zitiert:

${parameter:?word}
  

Wenn parameter gesetzt ist und nicht null ist dann seinen Wert ersetzen;   da ansonsten der Druck word und Austritt aus der Schale (wenn nicht interaktiv).   Wenn word weggelassen wird dann eine Standardmeldung gedruckt wird.

und

  

Wenn der Doppelpunkt : aus der obigen Ausdrücken weggelassen, dann ist die   Shell nur überprüft, ob Parameter gesetzt ist oder nicht.

Die Formulierung hier ist typisch für die Shell-Dokumentation, wie word beziehen zu jedem angemessenen Zeichenfolge, einschließlich Leerzeichen.

In diesem speziellen Fall weiß ich, dass die Standard-Fehlermeldung 1: parameter not set nicht ausreichend ist, so dass ich Zoom auf der Art des Wertes, den wir hier erwarten -. Den pathname eines Verzeichnisses

Ein philosophischer Hinweis: Die Schale ist nicht eine objektorientierte Sprache, so die Botschaft sagt pathname, nicht directory. Auf dieser Ebene würde ich es eher einfach halten - die Argumente für eine Funktion sind nur Strings

.
if [ -d "$Directory" -a -w "$Directory" ]
then
    #Statements
fi

Der obige Code überprüft, ob das Verzeichnis vorhanden ist und wenn es beschreibbar ist.

Geben Sie diesen Code auf der Bash-Eingabeaufforderung

if [ -d "$DIRECTORY" ]; then
  # if true this block of code will execute
fi

Weitere Funktionen mit find

  • Überprüfen 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 Existenz eines oder mehrere Ordner basierend auf einem Muster 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 folgende Beispiel wird es überprüft die Existenz des Ordners im aktuellen Verzeichnis:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi
    

Eigentlich sollten Sie verschiedene Tools verwenden, um einen kugelsicher Ansatz zu bekommen:

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

keine Notwendigkeit, über Leer- und Sonderzeichen sorgen, solange Sie "${}" verwenden.

Beachten Sie, dass [[]] als [] nicht tragbar ist, aber da die meisten Menschen mit modernen Versionen von Bash arbeiten (denn schließlich haben die meisten Menschen nicht einmal mit Kommandozeile :-P arbeiten), ist der Nutzen größer ist als die Mühe .

Um zu überprüfen, mehr als ein Verzeichnis verwendet diesen Code:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi

Haben Sie darüber nachgedacht nur tun, was Sie in der if tun wollen anstatt auf der Suche, bevor Sie springen?

IE, wenn Sie für die Existenz eines Verzeichnisses zu überprüfen, bevor Sie es eingeben, nur versuchen dies zu tun:

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

Wenn der Pfad, den Sie pushd geben vorhanden ist, werden Sie es eingeben und es wird mit 0 verlassen, der den then Teil der Aussage bedeutet, wird ausgeführt. Wenn es nicht vorhanden ist, wird nichts passieren (außer einigen Ausgängen sagten das Verzeichnis nicht existiert, das ist wahrscheinlich ein hilfreicher Nebeneffekt ist sowieso für das Debuggen).

Es scheint besser als das, was erfordert, zu wiederholen sich:

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

Das Gleiche gilt arbeitet 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 Ihre then Block wird übersprungen. Wenn Sie sie auf Dateien versuchen, die existieren, wird der Befehl ausführen und beenden mit einem Status von 0, so dass Ihr then Block auszuführen.

Überprüfen Sie, ob Verzeichnis vorhanden ist, sonst machen

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"
  

N. B:. Variablen Quoting ist eine gute Praxis

[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"

Diese Antwort als ein Shell-Skript verpackt

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";

Mit der -e Prüfung wird für Dateien überprüfen und diese Verzeichnisse umfasst.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi

Wie pro Jonathan Kommentar:

Wenn Sie das Verzeichnis erstellen möchten, und es existiert noch nicht, dann ist die einfachste Technik mkdir -p zu verwenden, die das Verzeichnis erstellt - und die fehlenden Verzeichnisse auf dem Weg - und nicht ausfällt, wenn das Verzeichnis bereits vorhanden ist, so dass Sie kann es sofort tun alles mit:

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

Das ist nicht ganz richtig ... Wenn Sie in das Verzeichnis gehen wollen, müssen Sie auch auf das Verzeichnis, das die Ausführungsrechte haben. Vielleicht benötigen Sie Schreibrechte sowie zu haben.

Therfore:

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

Der ls Befehl in Verbindung mit -l (lange Liste) Option kehrt Attribute Informationen über Dateien und Verzeichnisse.
Insbesondere das erste Zeichen des ls -l Ausgang ist es in der Regel ein oder eine d - (Strich). Im Fall eines d derjenige aufgeführt ist ein Verzeichnis, das ist sicher.

Mit dem folgenden Befehl in einer einzigen Zeile werden Ihnen sagen, ob die angegebene ISDIR Variable enthält einen Pfad zu einem Verzeichnis oder nicht:

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

Praktische Nutzung:

    [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
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;

Wenn Sie überprüfen möchten, ob ein Verzeichnis vorhanden ist, unabhängig davon, ob es ein echtes Verzeichnis oder ein symbolischer Link, verwenden Sie diese:

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

Erläuterung: Die „ls“ Befehl gibt eine Fehlermeldung „ls: / x: Keine solche Datei oder das Verzeichnis“, wenn das Verzeichnis oder Symlink nicht existiert, und setzt auch den Return-Code, mit dem Sie über abrufen können „$?“ , auf nicht-null (normalerweise "1"). Achten Sie darauf, dass Sie den Rückgabecode überprüfen direkt nach dem Aufruf von „ls“.

(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 ein Problem mit einem der oben genannten Ansätze festgestellt wird.

Mit ls Befehl;In den Fällen, in denen das Verzeichnis nicht existiert, wird eine Fehlermeldung angezeigt

$ [[ ls -ld SAMPLE_DIR| grep ^d | wc -l -Eq 1]] && echo existiert || nicht existiert -ksh:nicht:nicht gefunden [Keine solche Datei oder kein solches Verzeichnis]

Große Lösungen gibt, aber letztlich wird jedes Skript fehlschlagen, wenn Sie nicht im richtigen Verzeichnis sind. So 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 werden zur Zeit der Ausführung, wenn Sie in einem Verzeichnis sind, das ein Unterverzeichnis hat, die Sie passieren zu überprüfen.

verstehe ich die erste Frage wie folgt aus: um zu überprüfen, ob ein Verzeichnis unabhängig von der Position des Benutzers existiert im Dateisystem. So mit dem Befehl 'find' könnte den Trick tun:

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

Diese Lösung ist gut, weil es die Verwendung von Wildcards, eine nützliche Funktion ermöglicht, wenn für Dateien / Verzeichnisse durchsuchen. Das einzige Problem ist, dass, wenn das gesuchte Verzeichnis existiert nicht, die ‚find‘ Befehl nichts zu stdout gedruckt wird (nicht eine elegante Lösung für meinen Geschmack) und hat dennoch einen Nullausgang. Vielleicht könnte jemand auf diese verbessern.

Im Folgenden finden verwendet werden können,

find . -type d -name dirname -prune -print
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top