Bash se la dichiarazione con più condizioni genera un errore

Sto cercando di scrivere uno script che controlla due flag di errore, e nel caso in cui una bandiera (o entrambi) sono cambiate ti echo– errore è accaduto. Il mio script:

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

Fondamentalmente, dovrebbe essere, qualcosa di lungo:

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 incasinato?

InformationsquelleAutor Simply_me | 2013-04-24



4 Replies
  1. 204

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

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

    Aggiornamento

    In realtà si può ancora usare && e || con il -eq operazione. Quindi il tuo 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 si possono scartare le ultime due espressioni e solo bastone con uno o operazione di questo tipo:

    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
    • grazie per la rapida risposta, ma nel caso in cui entrambe le bandierine sono vere, non viola la condizione?
    • No, logico O è vera se entrambi i o sia dei suoi operandi sono veri. Stai pensando di o esclusivo (XOR), che è vero se uno solo dei suoi operandi è vero. (In realtà, ci sono versioni di XOR che opera su più di 2 operandi, nel qual caso è vero se un numero dispari di operandi sono veri.)
    • BTW, problemi nel codice originale includono l’utilizzo di [ e ] per il raggruppamento (non farlo), e di non mettere spazi intorno all’operatore (ad es. "$my_error_flag"="1"), che impedisce la shell da riconoscere in essa un operatore. Si prega di leggere BashFAQ #17 (in raggruppamento) e #31 (sulla differenza tra i diversi tipi di test di espressione). In realtà, in questo caso sarebbe anche più semplice da usare espressione aritmetica.
    • Grazie @GordonDavisson e per le vostre risposte dettagliate e riferimenti.
    • Grazie @mkhatib e per le vostre risposte dettagliate e riferimenti.
    • -a e -o sono considerati obsoleti da specifiche POSIX; utilizzare diversi test combinato con || come nell’aggiornamento.
    • Non c’è bisogno di un gruppo utilizzando subshells, normalmente raggruppamento utilizzando {} dovrebbe anche essere possibile.
    • per aggiungere a phk il commento di sopra, ( ) lancia subshells in bash, che possono avere tutti i tipi di sottile [probabilmente indesiderati] effetti.

  2. 52

    È possibile utilizzare [[ o (( parola chiave. Quando si utilizza [[ parola chiave, è necessario utilizzare operatori di stringa come -eq, -lt. Penso, (( è il più preferito per l’aritmetica, perché si può utilizzare direttamente gli 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 Dal momento che non è Portatile.

  3. 7

    Si prega di provare a seguire

    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!"
    • ( ... ) crea subshells-un sacco di impatto sulle prestazioni di alcun beneficio.
    • Utilizzare { ...; } per il raggruppamento senza subshell creazione.
  4. 1

    È possibile ottenere qualche ispirazione dalla lettura di un entrypoint.sh script scritto dagli autori di MySQL che controlla se specificato variabili sono state impostate.

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

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

Lascia un commento