Sprawdź, czy katalog istnieje w skrypcie powłoki

Jakiego polecenia można użyć do sprawdzenia, czy katalog istnieje, czy nie, w skrypcie powłoki?

Rozwiązanie

Aby sprawdzić, czy katalog istnieje w skrypcie powłoki, możesz użyć następującego polecenia:

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

Lub aby sprawdzić, czy katalog nie istnieje:

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

Jednakże, jak wskazuje Jon Ericson, kolejne polecenia mogą nie działać zgodnie z przeznaczeniem, jeśli nie weźmiemy pod uwagę, że dowiązanie symboliczne do katalogu również przejdzie to sprawdzenie. Np. uruchamiając to:

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

spowoduje wyświetlenie komunikatu o błędzie:

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

Tak więc dowiązania symboliczne mogą być traktowane inaczej, jeśli kolejne komendy oczekują katalogów:

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

Zwróć szczególną uwagę na podwójne cudzysłowy używane do zawijania zmiennych, powód tego jest wyjaśniony przez 8jean w innej odpowiedzi.

Jeśli zmienne zawierają spacje lub inne nietypowe znaki, prawdopodobnie spowoduje to niepowodzenie skryptu.

Komentarze (12)

Zwróć uwagę, że test -d może dać zaskakujące wyniki:

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

File under: "When is a directory not a directory?" Odpowiedź: "When it's a symlink to a directory." Nieco dokładniejszy test:

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

Więcej informacji można znaleźć w podręczniku Basha na temat wyrażeń warunkowych Basha oraz [[ wbudowanej komendy](https://www.gnu.org/software/bash/manual/bash.html#index-_005b) i [[[ komendy złożonej](https://www.gnu.org/software/bash/manual/bash.html#index-_005b_005b).

Komentarze (1)

Więcej funkcji przy użyciu find

  • Sprawdzanie istnienia folderu wewnątrz podkatalogów:

      found=`find -type d -name "myDirectory"`.
      if [ -n "$found"]
      then
          # Zmienna 'found' zawiera pełną ścieżkę gdzie jest "myDirectory".
          # Może zawierać kilka linii, jeśli istnieje kilka folderów o nazwie "myDirectory".
      fi
  • Sprawdza istnienie jednego lub kilku katalogów na podstawie wzorca w bieżącym katalogu:

      found=`find -maxdepth 1 -type d -name "my*"`.
      if [ -n "$found"]
      then
          # Zmienna 'found' zawiera pełną ścieżkę, gdzie zostały znalezione foldery "my*".
      fi
  • Obie kombinacje. W poniższym przykładzie sprawdzane jest istnienie folderu w bieżącym katalogu:

      found=`find -maxdepth 1 -type d -name "myDirectory"`.
      if [ -n "$found"]
      then
          # Zmienna 'found' nie jest pusta => "myDirectory"` istnieje.
      fi
Komentarze (1)