Ce comandă poate fi folosit pentru a verifica dacă un director există sau nu, într-un shell script?
Pentru a verifica dacă un director există într-un shell script puteți utiliza următoarele:
if [ -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY exists.
fi
Sau pentru a verifica dacă un director nu't există:
if [ ! -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY doesn't exist.
fi
Cu toate acestea, ca Jon Ericson subliniază, comenzile ulterioare nu poate funcționa corespunzător dacă nu ia în considerare faptul că o legătură simbolică la un director va trece, de asemenea, această verificare. E. g. rularea acest lucru:
ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then
rmdir "$SYMLINK"
fi
Va produce un mesaj de eroare:
rmdir: failed to remove `symlink': Not a directory
Deci, link-uri simbolice ar trebui să fie tratate în mod diferit, dacă comenzile ulterioare aștepta directoare:
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
Ia anumită notă de dublu-citate folosit pentru a încheia variabile, motivul pentru acest lucru este explicat prin 8jean într-un alt răspuns.
Dacă variabilele conțin spații sau alte caractere neobișnuite, probabil, va provoca script-ul pentru a eșua.
Amintiți-vă să întotdeauna folie de variabile în ghilimele atunci când fac referire la ele în un script bash. Copii în aceste zile să crească cu ideea că pot avea spații și o mulțime de alte personaje amuzante în directorul lor nume. (Spații! Înapoi în zilele mele, ne am't au nici o fantezie spații! ;))
Într-o zi, unul dintre acei copii vor rula scriptul cu $DIRECTOR
setat la `"Mea M0viez" și script-ul dvs. va exploda. Nu't vreau asta. Deci utilizați acest lucru.
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
Notă -d test poate produce unele rezultate surprinzătoare:
$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory
Fișierul sub: "atunci Când este un director nu un director?" răspuns: "la's o legătură simbolică la un director." Un pic mai aprofundată de testare:
if [ -d t ]; then
if [ -L t ]; then
rm t
else
rmdir t
fi
fi
Puteți găsi mai multe informații în Bash manual pe Bash expresiile condiționale și [[
builtin comanda](https://www.gnu.org/software/bash/manual/bash.html#index-_005b) și [[[
compus commmand](https://www.gnu.org/software/bash/manual/bash.html#index-_005b_005b).
Pentru a verifica dacă există un director, puteți utiliza simplu dacă structura astfel:
if [ -d directory/path to a directory ] ; then
#Things to do
else #if needed #also: elif [new condition]
# things to do
fi
Puteți face, de asemenea, în negativ
if [ ! -d directory/path to a directory ] ; then
# things to do when not an existing directory
Notă: Fi atent, lasă spații goale pe fiecare parte, cât de deschidere și de închidere bretele.
Cu aceeași sintaxă puteți folosi:
-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 /home/ram/dir ] # pentru fișier "if [-f /home/rama/fișier]" apoi echo "dir prezent" altceva echo "dir nu este prezent" fi
mkdir tempdir # dacă doriți să verificați fișierul utiliza tactil în loc de mkdir ret=$? dacă [ "$ret" == "0" ] apoi echo "dir prezent" altceva echo "dir nu este prezent" fi
Scripturile de mai sus va verifica dir este prezent sau nu
$?
dacă ultima comandă de suces se întoarce "0" altceva non valoarea zero.
să presupunem că tempdir
este deja prezentă atunci mkdir tempdir
va da eroare de genul de mai jos:
mkdir: nu se poate crea directorul 'tempdir': Fișierul există
if [ -d "$DIRECTORY" ]; then
# Here if $DIRECTORY exists
fi
Puteți utiliza test -d
(vezi om test
).
-d fișierul
True dacă fișierul există și este un director.
De exemplu:
test -d "/etc" && echo Exists || echo Does not exist
Notă: "test" comanda este același ca expresie condițională [
(a se vedea: man [
), deci's portabile peste un script shell.
[
- Aceasta este un sinonim pentru "test" interna, dar ultimul argument trebuie să fie un literal]
, pentru a se potrivi deschiderea[
.
Pentru opțiunile posibile sau ajuta în continuare, verificați:
ajutor [
test
Aici's un foarte pragmatic idiom:
(cd $dir) || return # is this a directory,
# and do we have access?
Eu de obicei înveliți-l într-o funcție:
can_use_as_dir() {
(cd ${1:?pathname expected}) || return
}
Sau:
assert_dir_access() {
(cd ${1:?pathname expected}) || exit
}
Cel mai frumos lucru despre această abordare este că nu trebuie să ne gândim la un bun mesaj de eroare.
"cd" va da-mi un standard singur mesaj stderr deja. Acesta va oferi, de asemenea, mai multe informații decât am va fi în măsură să ofere. Prin efectuarea " cd " în interiorul un subshell ( ... )
, comanda nu afectează actualul director al apelantului. Dacă directorul există, acest subshell și funcția sunt doar un no-op.
Următorul este argumentul care ne-am trece la "cd": ${1:?pathname de așteptat}
. Aceasta este o forma mai elaborata de parametru de substituție, care este explicat în detaliu mai jos.
Tl;dr: Dacă șirul trecut în această funcție este gol, am din nou ieșirea din subshell ( ... )
și reveni din funcție cu un mesaj de eroare.
Citez din `ksh93 om pagină:
${parameter:?word}
Dacă parametrul este setat și este non-null apoi înlocui valoarea acesteia; în caz contrar, print "cuvântul" și de ieșire de coajă (dacă nu interactivă). Dacă "cuvântul" este omis atunci un mesaj standard este imprimat.
și
Dacă colon
:
este omis din expresiile de mai sus, atunci shell verifică numai dacă parametrul este setat sau nu.
Frazare aici este specific coajă de documentare, precum "cuvântul" se poate referi pentru orice rezonabil șir de caractere, inclusiv spațiile.
În acest caz, știu că standardul mesaj de eroare de 1: parametru nu este setatnu este suficient, așa că am zoom pe tipul de valoare care ne-am aștepta aici -
cale` de un director.
Un philosphical notă:
Shell-ul nu este un limbaj orientat obiect, astfel încât mesajul spune cale
, nu director
. La acest nivel, am'd mai degrabă păstrați-l simplu - argumente pentru o funcție sunt doar siruri de caractere.
gasit=găsește -tip d -numele "myDirectory"
dacă [ -n "$a fost găsit"]
apoi
fi
gasit=găsește -maxdepth 1 -tip d -numele "mea*"
dacă [ -n "$a fost găsit"]
apoi
fi
gasit=găsește -maxdepth 1 -tip d -numele "myDirectory"
dacă [ -n "$a fost găsit"]
apoi
fi
De fapt, ar trebui să utilizați mai multe instrumente pentru a obține un antiglonț abordare:
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
Nu este nevoie să vă faceți griji despre spații și caractere speciale, atâta timp cât utilizați "${}"
.
Rețineți că [[]]
nu este la fel de portabil ca []
, dar din moment ce cei mai mulți oameni lucrează cu versiunile moderne de Bash (la urma urmei, cei mai mulți oameni don't lucra chiar și cu linie de comandă :-p), beneficiul este mai mare decât necazuri.
Te-ai gândit să faci doar ce vrei tu să faci în "dacă", mai degrabă decât în căutarea înainte de a sări?
De EXEMPLU, dacă doriți să verificați pentru existența unui director înainte de a intra în ea, încercați doar a face acest lucru:
if pushd /path/you/want/to/enter; then
# commands you want to run in this directory
popd
fi
Dacă calea dai la pushd
exista, tu'll introduceți-l și-l'll de ieșire de la "0", care înseamnă", apoi " parte din declarația va executa. Dacă nu't există, nimic nu se va întâmpla (altele decât niște ieșire spune directorul nu't există, care este, probabil, un ajutor efect secundar oricum pentru depanare).
Pare mai bună decât aceasta, care necesită repetarea tine:
if [ -d /path/you/want/to/enter ]; then
pushd /path/you/want/to/enter
# commands you want to run in this directory
popd
fi
Același lucru funcționează cu cd
, mv
, "rm", etc... dacă le încercați pe fișierele pe care don't există, ele'll ieși cu o eroare și a imprima un mesaj care spune că nu - 't există, și apoi
bloc vor fi ignorate. Dacă încercați-le pe fișierele care nu există, comanda se va executa și de ieșire cu un statut de "0", permițând", apoi " bloca pentru a executa.