2013-04-24 6 views
104

Sto provando a scrivere uno script che controllerà due flag di errore, e nel caso in cui venga modificato un flag (o entrambi) verrà echo-- errore accaduto. Il mio script:Bash se l'istruzione con più condizioni genera un errore

my_error_flag=0 
my_error_flag_o=0 
do something..... 
if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" &&  "$my_error_flag_o"="2" ]]; then 
    echo "$my_error_flag" 
else 
    echo "no flag" 
fi 

In sostanza, dovrebbe essere, qualcosa di simile:

if ((a=1 or b=2) or (a=1 and b=2)) 
    then 
    display error 
else 
    no error 
fi 

L'errore che ottengo è:

line 26: conditional binary operator expected 
line 26: syntax error near `]' 
line 26: `if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" && "$my_error_flag_o"="2" ]]; then' 

sono la mia parentesi in disordine?

+0

Check this out: http: //theunixshell.blogspot.com/2013/ 05/list-of-bash-condizionali-dichiarazioni.html – Vijay

+2

Usa parentesi -() –

+0

Vedi anche http://stackoverflow.com/questions/3826425/how-to-represent-multiple-conditions-in-a-shell- script – tripleee

risposta

167

Utilizzare -a (per e) e -o (per o) operazioni.

tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

Aggiornamento

In realtà si potrebbe ancora utilizzare && e || all'operazione -eq. Quindi, lo script sarebbe come questo:

my_error_flag=1 
my_error_flag_o=1 
if [ $my_error_flag -eq 1 ] || [ $my_error_flag_o -eq 2 ] || ([ $my_error_flag -eq 1 ] && [ $my_error_flag_o -eq 2 ]); then 
     echo "$my_error_flag" 
else 
    echo "no flag" 
fi 

Anche se nel tuo caso è possibile ignorare gli ultimi due espressioni e solo bastone con uno o un'operazione come questa:

my_error_flag=1 
my_error_flag_o=1 
if [ $my_error_flag -eq 1 ] || [ $my_error_flag_o -eq 2 ]; then 
     echo "$my_error_flag" 
else 
    echo "no flag" 
fi 
+0

grazie per la risposta rapida, ma nel caso che entrambi i flag siano veri, non violerà la condizione? –

+2

@Simply_Me: No, un OR logico è vero se entrambi * o entrambi * dei suoi operandi sono veri. Stai pensando a "esclusivo o" (XOR), che è vero se esattamente uno dei suoi operandi è vero. (In realtà, ci sono versioni di XOR che funzionano su più di 2 operandi, nel qual caso è vero se un numero dispari di operandi sono veri.) –

+3

BTW, i problemi nel codice originale includono l'utilizzo di '[' e ']' per il raggruppamento (non lo fanno), e non riuscendo a mettere spazi attorno all'operatore (es. "$ my_error_flag" = "1" '), che impedisce alla shell di riconoscerla come un operatore. Per favore leggi [BashFAQ # 17 (sul raggruppamento)] (http://mywiki.wooledge.org/BashFAQ/017) e [# 31 (sulla differenza tra i diversi tipi di espressione del test)] (http: //mywiki.wooledge .org/BashFAQ/031). In realtà, in questo caso sarebbe ancora più semplice usare una [espressione aritmetica] (http://mywiki.wooledge.org/ArithmeticExpression). –

38

È possibile utilizzare uno [[ o (( parola chiave. Quando si utilizza la parola chiave [[, è necessario utilizzare operatori di stringa come -eq, -lt. Penso che (( sia il più preferito per l'aritmetica, perché puoi utilizzare direttamente operatori come ==, < e >.

Utilizzando [[ operatore

a=$1 
b=$2 
if [[ a -eq 1 || b -eq 2 ]] || [[ a -eq 3 && b -eq 4 ]] 
then 
    echo "Error" 
else 
    echo "No Error" 
fi 

Utilizzando (( operatore

a=$1 
b=$2 
if ((a == 1 || b == 2)) || ((a == 3 && b == 4)) 
then 
    echo "Error" 
else 
    echo "No Error" 
fi 

Non utilizzare -a o -o operatori Dato che non è portatile.

1

È possibile ottenere qualche ispirazione leggendo uno entrypoint.shscript scritto dai contributori di MySQL che controlla se le variabili specificate sono state impostate.

Come lo script mostra, è possibile reindirizzare loro con -a, ad esempio:

if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then 
    ... 
fi 
3

Prova seguente

if ([ $dateR -ge 234 ] && [ $dateR -lt 238 ]) || ([ $dateR -ge 834 ] && [ $dateR -lt 838 ]) || ([ $dateR -ge 1434 ] && [ $dateR -lt 1438 ]) || ([ $dateR -ge 2034 ] && [ $dateR -lt 2038 ]) ; 
then 
    echo "WORKING" 
else 
    echo "Out of range!"