Molte volte, quando si scrivono script Shell, è possibile che ci si trovi in una situazione in cui è necessario eseguire un'azione in base all'esistenza o meno di un file.
In Bash, puoi utilizzare il comando test per verificare se esiste un file e determinare il tipo di file.
Il comando test assume una delle seguenti forme di sintassi:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
Se vuoi che il tuo script sia portabile, dovresti preferire usare il vecchio test [
comando, disponibile su tutte le shell POSIX. La nuova versione aggiornata del comando di test [[
(parentesi doppie) è supportato sulla maggior parte dei sistemi moderni che utilizzano Bash, Zsh e Ksh come shell predefinita.
Verifica se il file esiste #
Quando si controlla se esiste un file, gli operatori FILE più comunemente usati sono -e
e -f
. Il primo controllerà se esiste un file indipendentemente dal tipo, mentre il secondo restituirà true solo se il FILE è un file normale (non una directory o un dispositivo).
L'opzione più leggibile quando si controlla se un file esiste o meno è usare il test
comando in combinazione con if
dichiarazione. Uno degli snippet seguenti verificherà se il /etc/resolv.conf
il file esiste:
FILE=/etc/resolv.conf
if test -f "$FILE"; then
echo "$FILE exists."
fi
FILE=/etc/resolv.conf
if [ -f "$FILE" ]; then
echo "$FILE exists."
fi
FILE=/etc/resolv.conf
if [[ -f "$FILE" ]]; then
echo "$FILE exists."
fi
Se vuoi eseguire un'azione diversa a seconda che il file esista o meno, usa semplicemente il costrutto if/then:
FILE=/etc/resolv.conf
if [ -f "$FILE" ]; then
echo "$FILE exists."
else
echo "$FILE does not exist."
fi
Usa sempre virgolette doppie per evitare problemi quando hai a che fare con file contenenti spazi bianchi nei loro nomi.
Puoi anche usare il comando test senza l'istruzione if. Il comando dopo &&
l'operatore verrà eseguito solo se lo stato di uscita del comando di test è vero,
test -f /etc/resolv.conf && echo "$FILE exists."
[ -f /etc/resolv.conf ] && echo "$FILE exists."
[[ -f /etc/resolv.conf ]] && echo "$FILE exists."
Se vuoi eseguire una serie di comandi dopo &&
l'operatore racchiude semplicemente i comandi tra parentesi graffe separate da ;
o &&
:
[ -f /etc/resolv.conf ] && { echo "$FILE exist."; cp "$FILE" /tmp/; }
Di fronte a &&
, l'istruzione dopo il ||
l'operatore verrà eseguito solo se lo stato di uscita del comando di test è false
.
[ -f /etc/resolv.conf ] && echo "$FILE exist." || echo "$FILE does not exist."
Verifica se esiste una directory #
Gli operatori -d
consente di verificare se un file è una directory o meno.
Ad esempio per verificare se il /etc/docker
esiste una directory che useresti:
FILE=/etc/docker
if [ -d "$FILE" ]; then
echo "$FILE is a directory."
fi
[ -d /etc/docker ] && echo "$FILE is a directory."
Puoi anche usare le doppie parentesi [[
invece di uno solo [
.
Verifica se il file non esiste #
Simile a molti altri linguaggi, l'espressione di test può essere negata usando il !
(punto esclamativo) operatore non logico:
FILE=/etc/docker
if [ ! -f "$FILE" ]; then
echo "$FILE does not exist."
fi
Come sopra:
[ ! -f /etc/docker ] && echo "$FILE does not exist."
Verifica se esistono più file #
Invece di usare complicati costrutti nidificati if/else puoi usare -a
(o &&
con [[
) per verificare se esistono più file:
if [ -f /etc/resolv.conf -a -f /etc/hosts ]; then
echo "Both files exist."
fi
if [[ -f /etc/resolv.conf && -f /etc/hosts ]]; then
echo "Both files exist."
fi
Varianti equivalenti senza utilizzare l'istruzione IF:
[ -f /etc/resolv.conf -a -f /etc/hosts ] && echo "Both files exist."
[[ -f /etc/resolv.conf && -f /etc/hosts ]] && echo "Both files exist."
Operatori di test dei file #
Il comando test include i seguenti operatori FILE che ti consentono di testare particolari tipi di file:
-b
FILE
- Vero se il FILE esiste ed è un file di blocco speciale.-c
FILE
- Vero se il FILE esiste ed è un file di caratteri speciali.-d
FILE
- Vero se il FILE esiste ed è una directory.-e
FILE
- Vero se il FILE esiste ed è un file, indipendentemente dal tipo (nodo, directory, socket, ecc.).-f
FILE
- Vero se il FILE esiste ed è un file normale (non una directory o un dispositivo).-G
FILE
- Vero se il FILE esiste e ha lo stesso gruppo dell'utente che esegue il comando.-h
FILE
- Vero se il FILE esiste ed è un collegamento simbolico.-g
FILE
- Vero se il FILE esiste e ha set-group-id (sgid
) flag impostato.-k
FILE
- Vero se il FILE esiste e ha un flag bit permanente impostato.-L
FILE
- Vero se il FILE esiste ed è un collegamento simbolico.-O
FILE
- True se il FILE esiste ed è di proprietà dell'utente che esegue il comando.-p
FILE
- Vero se il FILE esiste ed è una pipe.-r
FILE
- Vero se il FILE esiste ed è leggibile.-S
FILE
- Vero se il FILE esiste ed è un socket.-s
FILE
- Vero se il FILE esiste e ha dimensioni diverse da zero.-u
FILE
- True se il FILE esiste e set-user-id (suid
) è impostato.-w
FILE
- Vero se il FILE esiste ed è scrivibile.-x
FILE
- Vero se il FILE esiste ed è eseguibile.
Conclusione #
In questa guida, ti abbiamo mostrato come verificare se un file o una directory esiste in Bash.
Se hai domande o feedback, sentiti libero di lasciare un commento.