Jak mogę sprawdzić, czy katalog istnieje w skrypcie powłoki Bash?

3719

Jakiej komendy można użyć do sprawdzenia, czy katalog istnieje w skrypcie powłoki Bash?

Grundlefleck
źródło

Odpowiedzi:

5145

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

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

Lub sprawdzić, czy katalog nie istnieje:

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

Jednak, jak zauważa Jon Ericson , kolejne polecenia mogą nie działać zgodnie z przeznaczeniem, jeśli nie weźmie się pod uwagę, że dowiązanie symboliczne do katalogu również przejdzie tę kontrolę. Np. Uruchomienie tego:

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

Wyświetli komunikat o błędzie:

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

Dlatego dowiązania symboliczne mogą wymagać innego traktowania, jeśli kolejne polecenia 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. Przyczynę tego wyjaśnia 8jean w innej odpowiedzi .

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

Grundlefleck
źródło
29
Jeśli chcesz grać bezpiecznie za pomocą narzędzi GNU, --wysoce zalecane jest użycie (znacznika końca opcji). W przeciwnym razie, jeśli twoja zmienna zawiera coś, co wygląda jak opcja, skrypt zawiedzie tak samo jak spacje.
Marc Mutz - mmutz
2
Dla nowoczesnych wersji bash, ksh itp. [...] jest wbudowanym
fpmurphy
79
Jedną z rzeczy, o których warto pamiętać: [ ! -d "$DIRECTORY" ]będzie prawdziwa albo jeśli $DIRECTORYnie istnieje, czy nie istnieje, ale nie jest katalogiem. Zastanów się nad czymś takim if [ ! -d "$DIRECTORY" ] ; then mkdir "$DIRECTORY" ; fi; to się nie powiedzie, jeśli "$DIRECTORY"jest to plik. (Oczywiście powinieneś sprawdzić, czy i mkdirtak się udało; istnieje wiele powodów, dla których może się nie powieść).
Keith Thompson,
5
Warto wspomnieć, że jak tylko kontrola zostanie wykonana, sytuacja może ulec zmianie już z powodu innych procesów. W wielu przypadkach lepiej jest po prostu utworzyć katalog lub użyć go i zareagować na awarię.
Alfe
12
Zamiast testować zarówno dla directory ( -d), jak i dowiązania symbolicznego ( -L), łatwiej jest po prostu dodać ukośnik do zmiennej, np if [ -d "${THING:+$THING/}" ]. Katalog nie będzie miał nic przeciwko dodatkowemu ukośnikowi. Plik zostanie oceniony jako fałszywy. Puste pozostanie puste, więc fałszywe. I dowiązanie symboliczne zostanie rozstrzygnięte do miejsca docelowego. Oczywiście zależy to od twojego celu. Jeśli chcesz się tam wybrać, nie ma sprawy. Jeśli chcesz go usunąć , kod w tej odpowiedzi jest lepszy.
ghoti
530

Pamiętaj, aby zawsze umieszczać zmienne w podwójnych cudzysłowach, odwołując się do nich w skrypcie Bash. W dzisiejszych czasach dzieci dorastają z myślą, że w nazwach katalogów mogą mieć spacje i wiele innych zabawnych postaci. (Przestrzenie! Za moich czasów nie mieliśmy żadnych wymyślnych miejsc!;))

Pewnego dnia jedno z tych dzieci uruchomi twój skrypt z $DIRECTORYustawionym na "My M0viez"i twój skrypt wybuchnie. Nie chcesz tego Więc skorzystaj z tego.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi
8jean
źródło
9
Innym powodem użycia podwójnych cudzysłowów jest przypadek, gdy $ DIRECTORY nie jest ustawiony z jakiegoś powodu.
Jon Ericson,
2
„zawsze zawijaj zmienne w podwójne cudzysłowy ... w skrypcie bash”. Dla bash, nie jest to technicznie konieczne przy użyciu [[...]]; patrz tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS (uwaga: bez dzielenia słów): „Żadne rozwijanie nazw plików ani dzielenie słów nie ma miejsca między [[i]], ale występuje rozszerzanie parametrów i zastępowanie poleceń”.
Michael
2
Katalogi w systemach Unix / Linux nie powinny mieć żadnych białych znaków, a następnie nie należy do nich dostosowywać skryptów. Jest wystarczająco źle, że Windows to obsługuje, ze wszystkimi konsekwencjami dla skryptów Windows, ale proszę, na miłość cokolwiek, nie trzeba wprowadzać niepotrzebnych wymagań.
tvCa
18
@tvCa Uważam, że użytkownicy zazwyczaj wolą mieć większą elastyczność w nazwach katalogów niż zmuszać programistów do ułatwienia. (W rzeczywistości, gdy mam do czynienia z długimi nazwami plików, uważam, że te bez spacji są uciążliwe, ponieważ zabija to zawijanie słów, nawet jeśli sam w przeszłości cierpiałem z powodu nieuwzględniania ścieżek ze spacjami w skryptach i programach.)
JAB
2
Ha. Spacje to po prostu znaki, które zwykle nie mają glifów. W każdym razie możesz uciec przed nimi odwrotnym ukośnikiem.
uchuugaka
228

Zauważ, ż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

Plik poniżej: „Kiedy katalog nie jest katalogiem?” Odpowiedź: „Gdy jest to dowiązanie symboliczne do katalogu”. 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 Bash na temat wyrażeń warunkowych Bash oraz [wbudowanego polecenia i polecenia [[złożonego .

Jon Ericson
źródło
12
lub, zakładając, że konieczna jest tylko praca na katalogach (i linki można zignorować) => if [ -d tmpdir -a ! -L tmpdir ]; then echo "is directory"; rmdir tmpdir; fi... lub, dla jednego polecenia, które działa na obu linkach i katalogach:rm -r tmpdir
Michał
218

Uważam, że wersja z podwójnymi nawiasamitest sprawia, że ​​pisanie testów logicznych jest bardziej naturalne:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi
yukondude
źródło
dla if [[ -d "$TARFILE" ]]Dostaję [[: Nie znaleziono
TheVillageIdiot
15
@TheVillageIdiot i @ Jeż, używasz powłoki bash? Podwójny nawias nie jest powszechnie obsługiwany. Oto odpowiedź SO na ten temat: stackoverflow.com/questions/669452/…
yukondude
6
A w Busybox ash [[ ]]jest obsługiwany z domyślnymi opcjami kompilacji , ale w rzeczywistości nie zapewnia żadnych innych funkcji [ ]. Jeśli problemem jest przenośność, trzymaj [ ]się koniecznych obejść i korzystaj z nich.
dubiousjim
6
... jeśli używasz konstrukcji bash w skrypcie powłoki, pierwszą linią skryptu powinna być: #! / bin / bash (a nie #! / bin / sh, ksh itp.)
michael
Gdy używasz podwójnych nawiasów kwadratowych w bash, nie musisz cytować zmiennych.
Hubert Grzeskowiak,
157

Krótsza forma:

[ -d "$DIR" ] && echo "Yes"
Elmarco
źródło
6
Czy to działa tak if $dir is a dir, then echo "yes":? Trochę wyjaśnienia pomogłoby :)
Martijn
5
cmd && otherjest częstym skrótem if cmd; then other; fi- działa z większością języków programowania obsługujących logikę boolowską i jest znany jako ocena zwarcia .
tripleee
1
Zachowanie nie jest takie samo pod set -e(co jest najlepszą praktyką programowania powłoki ).
dolmen
1
@dolmen [ -d "$DIR" ]jest zaznaczone (po którym następuje && echo Yes), więc uważam, set -eże nie ma znaczenia dla zachowania skryptu (tj. jeśli test się nie powiedzie, skrypt będzie kontynuował normalnie).
tzot
132

Aby sprawdzić, czy katalog istnieje, możesz użyć prostej ifstruktury takiej jak ta:

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

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

Możesz to również zrobić negatywnie:

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

Uwaga : bądź ostrożny. Pozostaw puste miejsca po obu stronach nawiasów otwierających i zamykających.

Przy tej samej składni możesz użyć:

-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
źródło
Jak to może być lepsze niż zaakceptowana odpowiedź z 2008 roku, poza wyjściem poza temat z przełącznikami plików?
Dan Dascalescu
lepiej, ponieważ [! -d katalog / ścieżka do katalogu]
użytkownik1855805
108
  1. Prosty skrypt do sprawdzenia, czy katalog lub plik jest obecny, czy nie:

    if [ -d /home/ram/dir ]   # For file "if [-f /home/rama/file]"
    then
        echo "dir present"
    else
        echo "dir not present"
    fi
  2. Prosty skrypt, aby sprawdzić, czy katalog jest obecny, czy nie:

    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

    Powyższe skrypty sprawdzą, czy katalog jest obecny, czy nie

    $? jeśli ostatnie polecenie zakończy się powodzeniem, zwraca „0”, w przeciwnym razie wartość niezerowa. Załóżmy, że tempdirjest już obecny. Następnie mkdir tempdirwyświetli błąd jak poniżej:

    mkdir: nie można utworzyć katalogu „tempdir”: plik istnieje

yoctotutor.com
źródło
4
Drugi utworzyłby katalog, gdyby początkowo nie istniał. To nie jest idempotentne.
Shihe Zhang
👆👆👆. Drugi wydaje się niebezpieczny. Ponieważ tworzy katalog, nie jest nawet prawdą, że katalog nie jest obecny.
Chris
92

Możesz użyć test -d(patrz man test).

-d file Prawda, jeśli plik istnieje i jest katalogiem.

Na przykład:

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

Uwaga: testpolecenie jest takie samo jak wyrażenie warunkowe [(patrz man [:), więc jest przenośne w skryptach powłoki.

[- To jest synonim testwbudowanego, ale ostatni argument musi być dosłowny ], aby pasował do otwarcia [.

Aby uzyskać dostępne opcje lub dalszą pomoc, sprawdź:

  • help [
  • help test
  • man test lub man [
kenorb
źródło
55

Lub coś zupełnie bezużytecznego:

[ -d . ] || echo "No"
coś
źródło
6
Nigdy nie wydrukuje „Nie”. Bieżący katalog zawsze istnieje, chyba że zostanie usunięty przez inny wątek lub w inny sposób.
Jahid
Idealna próbka :), biorąc pod uwagę, że „wyjątkowe” są niektóre odpowiedzi w porównaniu z odpowiedzią zaakceptowaną
Sergey Sargsyan
4
Dlaczego było to tak często oceniane? To nie odpowiada na pytanie.
codeforester
PONIEWAŻ NAJLEPSZA ODPOWIEDŹ EVA
Karl Morrison,
52

Oto bardzo pragmatyczny idiom:

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

Zazwyczaj pakuję go w funkcję:

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

Lub:

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

Zaletą tego podejścia jest to, że nie muszę myśleć o dobrym komunikacie o błędzie.

cdwyśle ​​mi już standardowy komunikat w jednym wierszu do standardowego błędu . Poda także więcej informacji, niż będę w stanie podać. Wykonując cdwewnątrz podpowłoki ( ... ), polecenie nie wpływa na bieżący katalog dzwoniącego. Jeśli katalog istnieje, ta podpowłoka i funkcja są po prostu niedostępne.

Dalej jest argument, że możemy przejść do cd: ${1:?pathname expected}. Jest to bardziej skomplikowana forma podstawiania parametrów, którą wyjaśniono bardziej szczegółowo poniżej.

Tl; dr: Jeśli ciąg przekazany do tej funkcji jest pusty, ponownie wychodzimy z podpowłoki ( ... )i wracamy z funkcji z podanym komunikatem o błędzie.


Cytowanie ze strony ksh93man:

${parameter:?word}

Jeśli parameter jest ustawiony i jest różny od zera, wówczas podstaw jego wartość; w przeciwnym razie wydrukuj wordi wyjdź z powłoki (jeśli nie jest interaktywny). Jeśli wordzostanie pominięty, zostanie wydrukowany standardowy komunikat.

i

Jeśli dwukropek :zostanie pominięty w powyższych wyrażeniach, wówczas powłoka sprawdza tylko, czy parametr jest ustawiony czy nie.

Frazowanie tutaj jest specyficzne dla dokumentacji powłoki, ponieważ wordmoże odnosić się do dowolnego rozsądnego ciągu, w tym białych znaków.

W tym konkretnym przypadku wiem, że standardowy komunikat o błędzie 1: parameter not setnie jest wystarczający, więc powiększam typ oczekiwanej tutaj pathnamewartości - katalogu.

Nota filozoficzna:

Powłoka nie jest językiem zorientowanym obiektowo, więc komunikat mówi pathname, że nie directory. Na tym poziomie wolę to uprościć - argumenty funkcji są tylko ciągami znaków.

Henk Langeveld
źródło
To więcej niż tylko sprawdzanie istnienia: Sprawdzanie dostępności na poziomie użytkownika. Pytanie SO oznacza tylko istnienie . Tak więc właściwa odpowiedź jest test -dtaka, jak wyjaśniono @Grundlefleck.
F. Hauri
7
@ F.Hauri - Nie prosił o nic więcej, to prawda. Przekonałem się jednak, że zazwyczaj muszę wiedzieć więcej.
Henk Langeveld
I nigdy nie przyszło mi do głowy, że żaden test nie może być rozstrzygający, chyba że działa jako root. test -d /unreadable/existszawiedzie, nawet jeśli argument istnieje.
Henk Langeveld
36
if [ -d "$Directory" -a -w "$Directory" ]
then
    #Statements
fi

Powyższy kod sprawdza, czy katalog istnieje i czy można go zapisać.

muralikrishna
źródło
1
-a działa identycznie jak -e. Został on „przestarzały”, a jego stosowanie jest odradzane.
CousinCocaine
27
DIRECTORY=/tmp

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

Wypróbuj online

Vishal
źródło
pamiętaj spacepo [-> [`` -d . dostałem błąd z powodu braku miejsca
Raj
4
PONOWNIE , odpowiedź ta została już udzielona w 2008 r., Wraz z bardziej przydatnymi wyjaśnieniami. Jedyną nowością jest tutaj plac zabaw online.
Dan Dascalescu
24

Wpisz ten kod w wierszu polecenia Bash:

if [ -d "$DIRECTORY" ]; then
    # If true this block of code will execute
fi
Santosh
źródło
PONOWNIE , ta odpowiedź została już udzielona w 2008 roku. Po co ją powtarzać ?!
Dan Dascalescu
21

Więcej funkcji za pomocą find

  • Sprawdź istnienie folderu w podkatalogach:

    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
  • Sprawdź istnienie jednego lub kilku folderów na podstawie wzorca w bieżącym katalogu:

    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
  • Obie kombinacje. W poniższym przykładzie sprawdza istnienie folderu w bieżącym katalogu:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi
Neil Neyman
źródło
Cześć Niel. Twój pomysł może być przydatna w celu sprawdzenia istnienia katalogów w zależności od wzoru, takich jak: find -maxdepth 1 -type d -name 'pattern'. Czy masz coś przeciwko, jeśli w odpowiedzi dodam tę sztuczkę? Pozdrawiam;)
olibre
20

Właściwie powinieneś użyć kilku narzędzi, aby uzyskać kuloodporne podejście:

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

Tak długo, jak używasz, nie musisz się martwić spacjami i znakami specjalnymi "${}".

Zauważ, że [[]]nie jest tak przenośny jak [], ale ponieważ większość ludzi pracuje z nowoczesnymi wersjami Bash (ponieważ w końcu większość ludzi nawet nie pracuje z wierszem poleceń :-p), korzyść jest większa niż kłopot.

e-satis
źródło
17

Czy zastanawiałeś się nad zrobieniem tego, co chcesz, ifzamiast patrzeć przed skokiem?

To znaczy, jeśli chcesz sprawdzić istnienie katalogu przed jego wprowadzeniem, spróbuj zrobić to:

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

Jeśli ścieżka, którą podajesz, pushdistnieje, wprowadzisz ją i zakończysz za pomocą 0, co oznacza, że thenczęść instrukcji zostanie wykonana. Jeśli nie istnieje, nic się nie wydarzy (oprócz niektórych danych wyjściowych, że katalog nie istnieje, co jest prawdopodobnie pomocnym efektem ubocznym przy debugowaniu).

Wydaje się to lepsze niż to, co wymaga powtórzenia się:

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

To samo działa z cd, mv, rm, etc ... jeśli spróbujesz je na pliki, które nie istnieją, będą mogły wyjść z błędu i wydrukować wiadomość, mówiąc, że nie istnieje, a thenblok zostanie pominięty. Jeśli wypróbujesz je na istniejących plikach, polecenie zostanie wykonane i zakończy się ze statusem 0, umożliwiając thenwykonanie bloku.

ArtOfWarfare
źródło
2
pushd jest dla mnie najbardziej eleganckim sposobem na zrobienie tego.
Właśnie
15

Aby sprawdzić więcej niż jeden katalog, użyj tego kodu:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi
Raamesh Keerthi
źródło
jak możesz sprawdzić, czy nie istnieje?
perrohunter
15

Sprawdź, czy katalog istnieje, w przeciwnym razie utwórz go:

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
David Okwii
źródło
16
Możesz użyć mkdir -p "$DIRECTORY"tego samego efektu.
Logan Pickup
15
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

NB: Cytowanie zmiennych jest dobrą praktyką.

Wyjaśnienie:

  • -d: sprawdź, czy to katalog
  • -L: sprawdź, czy jest to link symboliczny
Jahid
źródło
Wyjaśnienie byłoby w porządku ( edytując odpowiedź , a nie tutaj w komentarzach).
Peter Mortensen
13
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"
Juan Carlos Kuri Pinto
źródło
Wyjaśnienie byłoby w porządku ( edytując odpowiedź , a nie tutaj w komentarzach).
Peter Mortensen
11

Ta odpowiedź jest zapakowana jako skrypt powłoki

Przykłady

$ 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
źródło
10

Użycie tej opcji -esprawdzi, czy są dostępne pliki, w tym katalogi.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi
bailey86
źródło
1
I nie odpowiada poprawnie na pytanie PO - czy to katalog?
Mark Stewart
8

Zgodnie z komentarzem Jonathana :

Jeśli chcesz utworzyć katalog, który jeszcze nie istnieje, to najprostszą techniką jest użycie tego, mkdir -pktóry tworzy katalog - i wszelkie brakujące katalogi na ścieżce - i nie zawiedzie, jeśli katalog już istnieje, więc możesz zrobić to wszystko od razu z:

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

To nie do końca prawda ...

Jeśli chcesz przejść do tego katalogu, musisz także mieć uprawnienia do wykonywania tego katalogu. Być może musisz również mieć prawa do zapisu.

W związku z tym:

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
źródło
7

Skorzystaj z fileprogramu. Biorąc pod uwagę, że wszystkie katalogi są również plikami w systemie Linux, wystarczyłoby wykonać następujące polecenie:

file $directory_name

Sprawdzanie nieistniejącego pliku: file blah

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

Sprawdzanie istniejącego katalogu: file bluh

Wynik: bluh: directory

Sudip Bhandari
źródło
1
Fajny pomysł, jednak w obu przypadkach szkoda, że ​​polecenie file zawsze zwraca 0 kod wyjścia. Również wtedy, gdy nie można znaleźć pliku / katalogu :(.
danger89
6

lsPolecenia w połączeniu z -l(długie liście) deklaracji atrybutów opcjonalnych informacji o plikach i katalogach.
W szczególności pierwszym znakiem ls -lwyjścia jest zwykle a dlub -myślnik. W przypadku djednego z wymienionych jest na pewno katalog.

Poniższe polecenie w jednym wierszu powie ci, czy dana ISDIRzmienna zawiera ścieżkę do katalogu, czy nie:

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

Praktyczne zastosowanie:

    [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
źródło
+1, ale gdy ISDIR w ogóle nie istnieje, pojawia się komunikat o błędzie oraz komunikat diagnostyczny.
ysap
5
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;
ajmartin
źródło
Wyjaśnienie byłoby w porządku ( edytując odpowiedź , a nie tutaj w komentarzach).
Peter Mortensen
5

Jeśli chcesz sprawdzić, czy katalog istnieje, niezależnie od tego, czy jest to prawdziwy katalog, czy dowiązanie symboliczne, użyj tego:

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

Objaśnienie: Komenda „ls” wyświetla błąd „ls: / x: Brak takiego pliku lub katalogu”, jeśli katalog lub dowiązanie symboliczne nie istnieje, a także ustawia kod powrotu, który można pobrać za pomocą „$?”, Na wartość inną niż -null (zwykle „1”). Pamiętaj, aby sprawdzić kod powrotu bezpośrednio po wywołaniu „ls”.

derFunk
źródło
3
Alternatywnie możesz użyć tej krótszej wersji: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"

Jeśli zostanie znaleziony problem z jednym z powyższych sposobów:

Z lsrozkazem; przypadki, gdy katalog nie istnieje - wyświetlany jest komunikat o błędzie

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

-ksh: not: not found [Brak takiego pliku lub katalogu]

Piyush Baijal
źródło
Do czego odnosi się „powyżej”? Trzy linie poleceń w tej odpowiedzi lub poprzednich odpowiedziach? ( Odpowiedz , edytując odpowiedź , a nie w komentarzach. Z góry dziękuję).
Peter Mortensen
4

Istnieją świetne rozwiązania, ale ostatecznie każdy skrypt zawiedzie, jeśli nie znajdziesz się w odpowiednim katalogu. Więc kod taki:

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

wykona się pomyślnie tylko wtedy, gdy w chwili wykonania znajdujesz się w katalogu z podkatalogiem, którego szukasz.

Rozumiem początkowe pytanie w ten sposób: aby sprawdzić, czy katalog istnieje niezależnie od pozycji użytkownika w systemie plików. Zatem użycie polecenia „znajdź” może załatwić sprawę:

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

To rozwiązanie jest dobre, ponieważ pozwala na użycie symboli wieloznacznych, użytecznej funkcji podczas wyszukiwania plików / katalogów. Jedyny problem polega na tym, że jeśli przeszukiwany katalog nie istnieje, polecenie „znajdź” nie wypisuje nic na standardowe wyjście (nie jest to eleganckie rozwiązanie według mojego gustu) i mimo to ma zerowe wyjście. Może ktoś mógłby to poprawić.

dromichaetes
źródło
13
Byłbym obrażony, gdyby jakiś program przeszukał cały mój dysk twardy, aby znaleźć katalog, zamiast grzecznie szukać w moim bieżącym katalogu roboczym lub korzystając z absolutnej ścieżki, którą mu podałem. To, co zasugerowałeś, może być dobre dla narzędzia o nazwie, locateale nie dla niczego innego ...
sarnold