Bash
Strutture di controllo
Ricerca…
Sintassi
- ["$ 1" = "$ 2"] #A La parentesi "[" è in realtà un comando. Per questo richiede uno spazio prima e dopo di esso.
- test "$ 1" = "$ 2" # Test è un sinonimo per il comando "["
Parametri
Parametro per [o test | Dettagli |
---|---|
Operatori di file | Dettagli |
-e "$file" | Restituisce vero se il file esiste. |
-d "$file" | Restituisce vero se il file esiste ed è una directory |
-f "$file" | Restituisce vero se il file esiste ed è un file normale |
-h "$file" | Restituisce vero se il file esiste ed è un collegamento simbolico |
Comparatori di stringhe | Dettagli |
-z "$str" | Vero se la lunghezza della stringa è zero |
-n "$str | Vero se la lunghezza della stringa è diversa da zero |
"$str" = "$str2" | Vero se stringa $ str è uguale a stringa $ str2. Non è il migliore per i numeri interi. Potrebbe funzionare ma sarà inconsistente |
"$str" != "$str2" | Vero se le stringhe non sono uguali |
Comparatori interi | Dettagli |
"$int1" -eq "$int2" | Vero se gli interi sono uguali |
"$int1" -ne "$int2" | Vero se gli interi non sono uguali |
"$int1" -gt "$int2" | Vero se int1 è maggiore di int 2 |
"$int1" -ge "$int2" | Vero se int1 è maggiore o uguale a int2 |
"$int1" -lt "$int2" | Vero se int1 è minore di int 2 |
"$int1" -le "$int2" | Vero se int1 è minore o uguale a int2 |
Osservazioni
Ci sono molti parametri di confronto disponibili in bash. Non tutti sono ancora elencati qui.
Se la dichiarazione
if [[ $1 -eq 1 ]]; then
echo "1 was passed in the first parameter"
elif [[ $1 -gt 2 ]]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
Il fi
chiusura è necessario, ma le elif
e / o le else
clausole possono essere omesse.
I punti e virgola prima di then
sono la sintassi standard per combinare due comandi su una singola riga; possono essere omessi solo se then
vengono spostati nella riga successiva.
È importante capire che le parentesi [[
non fanno parte della sintassi, ma sono trattate come un comando; è il codice di uscita da questo comando che viene testato. Pertanto, devi sempre includere spazi attorno alle parentesi.
Ciò significa anche che il risultato di qualsiasi comando può essere testato. Se il codice di uscita dal comando è uno zero, l'istruzione è considerata vera.
if grep "foo" bar.txt; then
echo "foo was found"
else
echo "foo was not found"
fi
Le espressioni matematiche, se poste all'interno di doppie parentesi, restituiscono anche 0 o 1 nello stesso modo e possono anche essere testate:
if (( $1 + 5 > 91 )); then
echo "$1 is greater than 86"
fi
Si può anche venire attraverso if
istruzioni con parentesi quadre singole. Questi sono definiti nello standard POSIX e sono garantiti per funzionare in tutti gli shell conformi a POSIX incluso Bash. La sintassi è molto simile a quella in Bash:
if [ "$1" -eq 1 ]; then
echo "1 was passed in the first parameter"
elif [ "$1" -gt 2 ]; then
echo "2 was not passed in the first parameter"
else
echo "The first parameter was not 1 and is not more than 2."
fi
Mentre Loop
#! /bin/bash
i=0
while [ $i -lt 5 ] #While i is less than 5
do
echo "i is currently $i"
i=$[$i+1] #Not the lack of spaces around the brackets. This makes it a not a test expression
done #ends the loop
Guarda che ci sono spazi attorno alle parentesi durante il test (dopo l'istruzione while). Questi spazi sono necessari.
Questo loop emette:
i is currently 0
i is currently 1
i is currently 2
i is currently 3
i is currently 4
Per Loop
#! /bin/bash
for i in 1 "test" 3; do #Each space separated statement is assigned to i
echo $i
done
Altri comandi possono generare istruzioni da ripetere. Vedi l'esempio "Utilizzo del ciclo per scorrere i numeri".
Questo produce:
1
test
3
Usando Per Loop per elencare Iterate Over Numbers
#! /bin/bash
for i in {1..10}; do # {1..10} expands to "1 2 3 4 5 6 7 8 9 10"
echo $i
done
Questo produce quanto segue:
1
2
3
4
5
6
7
8
8
10
Per Loop con sintassi in stile C.
Il formato di base di C-style for
loop è:
for (( variable assignment; condition; iteration process ))
Gli appunti:
- L'assegnazione della variabile all'interno di C
for
ciclo può contenere spazi diversi dal solito compito - Le variabili all'interno di C-style
for
loop non sono precedute da$
.
Esempio:
for (( i = 0; i < 10; i++ ))
do
echo "The iteration number is $i"
done
Inoltre possiamo elaborare più variabili all'interno di C-style for
loop:
for (( i = 0, j = 0; i < 10; i++, j = i * i ))
do
echo "The square of $i is equal to $j"
done
Until Loop
Until loop viene eseguito fino a quando la condizione è vera
i=5
until [[ i -eq 10 ]]; do #Checks if i=10
echo "i=$i" #Print the value of i
i=$((i+1)) #Increment i by 1
done
Produzione:
i=5
i=6
i=7
i=8
i=9
Quando i
raggiunge il 10 la condizione in until diventa vero e il ciclo termina.
continua e rompi
Esempio per continuare
for i in [series]
do
command 1
command 2
if (condition) # Condition to jump over command 3
continue # skip to the next value in "series"
fi
command 3
done
Esempio di pausa
for i in [series]
do
command 4
if (condition) # Condition to break the loop
then
command 5 # Command if the loop needs to be broken
break
fi
command 6 # Command to run if the "condition" is never true
done
In loop su un array
for
ciclo:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
done
O
for ((i=0;i<${#arr[@]};i++));do
echo "${arr[$i]}"
done
ciclo while
:
i=0
while [ $i -lt ${#arr[@]} ];do
echo "${arr[$i]}"
i=$(expr $i + 1)
done
O
i=0
while (( $i < ${#arr[@]} ));do
echo "${arr[$i]}"
((i++))
done
Loop break
Rompi loop multipli:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break 2
done
done
Produzione:
a
a
Rompere il loop singolo:
arr=(a b c d e f)
for i in "${arr[@]}";do
echo "$i"
for j in "${arr[@]}";do
echo "$j"
break
done
done
Produzione:
a
a
b
a
c
a
d
a
e
a
f
a
Passare la dichiarazione con il caso
Con l'istruzione case
puoi confrontare i valori con una variabile.
L'argomento passato a case
è espanso e tenta di corrispondere a ogni modello.
Se viene trovata una corrispondenza, i comandi ;;
fino a ;;
sono eseguiti
case "$BASH_VERSION" in
[34]*)
echo {1..4}
;;
*)
seq -s" " 1 4
esac
I pattern non sono espressioni regolari ma pattern matching shell (noti anche come glob).
Per loop senza un parametro list-of-words
for arg; do
echo arg=$arg
done
Un ciclo for
senza un parametro list of words eseguirà invece iterazioni sui parametri posizionali. In altre parole, l'esempio sopra è equivalente a questo codice:
for arg in "$@"; do
echo arg=$arg
done
In altre parole, se ti sorprendi a scrivere for i in "$@"; do ...; done
, basta semplicemente inserire il in
parte, e scrivere semplicemente for i; do ...; done
.
Esecuzione condizionale di liste di comandi
Come utilizzare l'esecuzione condizionale degli elenchi di comandi
Qualsiasi comando, espressione o funzione incorporati, così come qualsiasi comando o script esterno possono essere eseguiti in modo condizionale usando &&
(e) e ||
(o) operatori.
Ad esempio, questo stamperà solo la directory corrente se il comando cd
avuto successo.
cd my_directory && pwd
Allo stesso modo, uscirà se il comando cd
fallisce, impedendo la catastrofe:
cd my_directory || exit
rm -rf *
Quando si combinano più affermazioni in questo modo, è importante ricordare che (a differenza di molti linguaggi in stile C) questi operatori non hanno precedenza e sono associati a sinistra .
Quindi, questa affermazione funzionerà come previsto ...
cd my_directory && pwd || echo "No such directory"
- Se il
cd
successo, viene eseguito&& pwd
e viene stampato il nome corrente della directory di lavoro. Salvopwd
(una rarità) il|| echo ...
non verrà eseguito. - Se il
cd
fallisce, il&& pwd
verrà saltato e il|| echo ...
funzionerà.
Ma questo non lo farà (se stai pensando if...then...else
) ...
cd my_directory && ls || echo "No such directory"
- Se il
cd
fallisce, il&& ls
viene saltato e il|| echo ...
viene eseguito. - Se il
cd
successo, viene eseguito&& ls
.- Se
ls
riesce, il|| echo ...
è ignorato. (Fin qui tutto bene) - MA ... se la
ls
fallisce, il|| echo ...
verrà eseguito anche.È il
ls
, non ilcd
, che è il comando precedente .
- Se
Perché usare l'esecuzione condizionale degli elenchi di comandi
L'esecuzione condizionale è un capello più veloce di if...then
ma il suo vantaggio principale è consentire a funzioni e script di uscire presto, o "cortocircuito".
A differenza di molti linguaggi come C
cui la memoria è allocata esplicitamente per le strutture e le variabili e tale (e quindi deve essere deallocato), bash
gestisce sotto le coperte. Nella maggior parte dei casi, non è necessario pulire nulla prima di lasciare la funzione. Un'istruzione return
tutto ciò che è locale alla funzione e l'esecuzione pickup all'indirizzo di ritorno nello stack.
Il ritorno dalle funzioni o l'uscita degli script il prima possibile può quindi migliorare significativamente le prestazioni e ridurre il carico del sistema evitando l'esecuzione non necessaria del codice. Per esempio...
my_function () {
### ALWAYS CHECK THE RETURN CODE
# one argument required. "" evaluates to false(1)
[[ "$1" ]] || return 1
# work with the argument. exit on failure
do_something_with "$1" || return 1
do_something_else || return 1
# Success! no failures detected, or we wouldn't be here
return 0
}