Bash
Espressioni condizionali
Ricerca…
Sintassi
- [[-OP $ nomefile]]
- [[$ file1 -OP $ file2]]
- [[-z $ string]]
- [[-n $ stringa]]
- [["$ stringa1" == "$ stringa2"]]
- [["$ stringa1" == $ modello]]
Osservazioni
La sintassi [[ … ]]
circonda le espressioni condizionali bash incorporate. Notare che sono richiesti spazi su entrambi i lati delle parentesi.
Le espressioni condizionali possono utilizzare gli operatori unari e binari per verificare le proprietà di stringhe, numeri interi e file. Possono anche utilizzare gli operatori logici &&
, ||
e !
.
Confronto dei file
if [[ $file1 -ef $file2 ]]; then
echo "$file1 and $file2 are the same file"
fi
"Stesso file" significa che la modifica di uno dei file sul posto influisce sull'altro. Due file possono essere uguali anche se hanno nomi diversi, ad esempio se sono collegamenti fisici o se sono collegamenti simbolici con lo stesso target o se uno è un collegamento simbolico che punta all'altro.
Se due file hanno lo stesso contenuto, ma sono file distinti (in modo che la modifica di uno non influisca sull'altro), quindi -ef
li segnala come diversi. Se si desidera confrontare due file byte per byte, utilizzare l'utilità cmp
.
if cmp -s -- "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
echo "$file1 and $file2 differ"
fi
Per produrre un elenco di differenze leggibili tra file di testo, utilizzare l'utilità diff
.
if diff -u "$file1" "$file2"; then
echo "$file1 and $file2 have identical contents"
else
: # the differences between the files have been listed
fi
Test di accesso ai file
if [[ -r $filename ]]; then
echo "$filename is a readable file"
fi
if [[ -w $filename ]]; then
echo "$filename is a writable file"
fi
if [[ -x $filename ]]; then
echo "$filename is an executable file"
fi
Questi test prendono in considerazione le autorizzazioni e la proprietà per determinare se lo script (oi programmi avviati dallo script) possono accedere al file.
Attenzione alle condizioni di gara (TOCTOU) : solo perché il test ha successo ora non significa che sia ancora valido sulla riga successiva. Di solito è meglio provare ad accedere a un file e gestire l'errore, piuttosto che eseguire prima il test e poi gestire l'errore in ogni caso nel caso in cui il file sia cambiato nel frattempo.
Confronti numerici
I confronti numerici usano gli operatori e gli amici -eq
if [[ $num1 -eq $num2 ]]; then
echo "$num1 == $num2"
fi
if [[ $num1 -le $num2 ]]; then
echo "$num1 <= $num2"
fi
Esistono sei operatori numerici:
-
-eq
uguale -
-ne
è uguale -
-le
meno o uguale -
-lt
meno di -
-ge
maggiore o uguale -
-gt
maggiore di
Nota che gli operatori <
e >
all'interno di [[ … ]]
confrontano le stringhe, non i numeri.
if [[ 9 -lt 10 ]]; then
echo "9 is before 10 in numeric order"
fi
if [[ 9 > 10 ]]; then
echo "9 is after 10 in lexicographic order"
fi
I due lati devono essere numeri scritti in decimale (o in ottale con uno zero iniziale). In alternativa, utilizzare la sintassi di espressione aritmetica ((…))
, che esegue calcoli integer in una sintassi C / Java / ... -like.
x=2
if ((2*x == 4)); then
echo "2 times 2 is 4"
fi
((x += 1))
echo "2 plus 1 is $x"
Confronto e corrispondenza delle stringhe
Il confronto tra stringhe usa l'operatore ==
tra le stringhe tra virgolette . L'operatore !=
Nega il confronto.
if [[ "$string1" == "$string2" ]]; then
echo "\$string1 and \$string2 are identical"
fi
if [[ "$string1" != "$string2" ]]; then
echo "\$string1 and \$string2 are not identical"
fi
Se il lato destro non è quotato, si tratta di un modello jolly con cui viene confrontato $string1
.
string='abc'
pattern1='a*'
pattern2='x*'
if [[ "$string" == $pattern1 ]]; then
# the test is true
echo "The string $string matches the pattern $pattern"
fi
if [[ "$string" != $pattern2 ]]; then
# the test is false
echo "The string $string does not match the pattern $pattern"
fi
Gli operatori <
e >
confrontano le stringhe in ordine lessicografico (non ci sono operatori meno o meno uguali o maggiori per le stringhe).
Esistono test unari per la stringa vuota.
if [[ -n "$string" ]]; then
echo "$string is non-empty"
fi
if [[ -z "${string// }" ]]; then
echo "$string is empty or contains only spaces"
fi
if [[ -z "$string" ]]; then
echo "$string is empty"
fi
Sopra, il controllo -z
può significare che $string
non è impostata, o è impostata su una stringa vuota. Per distinguere tra vuoto e non impostato, utilizzare:
if [[ -n "${string+x}" ]]; then
echo "$string is set, possibly to the empty string"
fi
if [[ -n "${string-x}" ]]; then
echo "$string is either unset or set to a non-empty string"
fi
if [[ -z "${string+x}" ]]; then
echo "$string is unset"
fi
if [[ -z "${string-x}" ]]; then
echo "$string is set to an empty string"
fi
dove x
è arbitrario. O in forma di tabella :
+-------+-------+-----------+
$string is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [[ -z ${string} ]] | true | true | false |
| [[ -z ${string+x} ]] | true | false | false |
| [[ -z ${string-x} ]] | false | true | false |
| [[ -n ${string} ]] | false | false | true |
| [[ -n ${string+x} ]] | false | true | true |
| [[ -n ${string-x} ]] | true | false | true |
+-----------------------+-------+-------+-----------+
In alternativa , lo stato può essere controllato in una dichiarazione del caso:
case ${var+x$var} in
(x) echo empty;;
("") echo unset;;
(x*[![:blank:]]*) echo non-blank;;
(*) echo blank
esac
Dove [:blank:]
è caratteri di spaziatura orizzontale specifici della locale (tab, spazio, ecc.).
Test del tipo di file
L'operatore condizionale -e
verifica se esiste un file (inclusi tutti i tipi di file: directory, ecc.).
if [[ -e $filename ]]; then
echo "$filename exists"
fi
Esistono anche test per tipi di file specifici.
if [[ -f $filename ]]; then
echo "$filename is a regular file"
elif [[ -d $filename ]]; then
echo "$filename is a directory"
elif [[ -p $filename ]]; then
echo "$filename is a named pipe"
elif [[ -S $filename ]]; then
echo "$filename is a named socket"
elif [[ -b $filename ]]; then
echo "$filename is a block device"
elif [[ -c $filename ]]; then
echo "$filename is a character device"
fi
if [[ -L $filename ]]; then
echo "$filename is a symbolic link (to any file type)"
fi
Per un collegamento simbolico, ad eccezione di -L
, questi test si applicano al target e restituiscono false per un collegamento interrotto.
if [[ -L $filename || -e $filename ]]; then
echo "$filename exists (but may be a broken symbolic link)"
fi
if [[ -L $filename && ! -e $filename ]]; then
echo "$filename is a broken symbolic link"
fi
Test sullo stato di uscita di un comando
Stato di uscita 0: successo
Stato di uscita diverso da 0: errore
Per verificare lo stato di uscita di un comando:
if command;then
echo 'success'
else
echo 'failure'
fi
Un test di linea
Puoi fare cose come questa:
[[ $s = 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s == 'something' ]] && echo 'matched' || echo "didn't match"
[[ $s != 'something' ]] && echo "didn't match" || echo "matched"
[[ $s -eq 10 ]] && echo 'equal' || echo "not equal"
(( $s == 10 )) && echo 'equal' || echo 'not equal'
Un test di linea per lo stato di uscita:
command && echo 'exited with 0' || echo 'non 0 exit'
cmd && cmd1 && echo 'previous cmds were successful' || echo 'one of them failed'
cmd || cmd1 #If cmd fails try cmd1