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


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow