Come eseguire un'operazione OR logica nello script di shell


571

Sto cercando di fare un semplice controllo delle condizioni, ma non sembra funzionare.

Se $#è uguale 0o è maggiore di 1allora saluta.

Ho provato la seguente sintassi senza successo:

if [ "$#" == 0 -o "$#" > 1 ] ; then
 echo "hello"
fi

if [ "$#" == 0 ] || [ "$#" > 1 ] ; then
 echo "hello"
fi

Entrambi lavorano per me. Hai specificato una shell nella linea shebang ?
Jason McCreary,

1
@Jason In realtà ho dimenticato la linea Shebang, ma l'ho testata proprio ora e non ha funzionato.
Strawberry,

25
>è il reindirizzamento dell'output in sh / bash. Ora probabilmente hai un file chiamato 1.
mark4o

Per informazioni sui confronti di Bash, vedere le mie risposte alle domande precedenti qui e qui . Per ulteriori informazioni su parentesi, doppie parentesi e doppie parentesi, vedere la mia risposta qui .
In pausa fino a nuovo avviso.

Non funziona perché digiti male il buyison: usa "$ #" == "0" o $ # -eq 0
ETech

Risposte:


987

Questo dovrebbe funzionare:

#!/bin/bash

if [ "$#" -eq 0 ] || [ "$#" -gt 1 ] ; then
    echo "hello"
fi

Non sono sicuro che questo sia diverso in altre shell ma se si desidera utilizzare <,>, è necessario inserirle tra parentesi doppie in questo modo:

if (("$#" > 1))
 ...

2
Non sono sicuro che sia diverso in un'altra shell ma in bash, se si desidera utilizzare> o <, è necessario metterli tra parentesi doppie in questo modo: (("" $ a "<" $ b "))
Coding Distretto

1
@Doug: Non è che unix non li usi, è che bash e tutte le altre shell che conosco li usano per il reindirizzamento input / output.
Cascabel,

56

Questo codice funziona per me:

#!/bin/sh

argc=$#
echo $argc
if [ $argc -eq 0 -o $argc -eq 1 ]; then
  echo "foo"
else
  echo "bar"
fi

Non credo che sh supporti "==". Usa "=" per confrontare stringhe e -eq per confrontare ints.

man test

per ulteriori dettagli.


Qual è l'opzione per maggiore di? Dov'è la documentazione ufficiale per Tihs?
Strawberry,

3
Dovrebbe essere -gtper maggiore di. O semplicemente sostituire tutto con [ $# -ne 1 ].
mark4o

Maggiore di -gt, vedi la mia risposta. La documentazione ufficiale è in fase di test, come ha sottolineato Jbremnant.
Coding District,

Proprio come un amico per gli altri, a seconda della shell, la maggior parte supporta == (ora un giorno) come operatore di confronto, tuttavia il più delle volte è uguale all'operatore =. Immagino che se stai usando -gt e -ne per i confronti sarebbe meglio usare -eq per == o = per mantenere coerente il tuo stile di scripting. Happy Bashing :)
jkdba,

34

Se si utilizza lo stato del codice di uscita bash $? come variabile, è meglio fare questo:

if [ $? -eq 4 -o $? -eq 8 ] ; then  
   echo "..."
fi

Perché se lo fai:

if [ $? -eq 4 ] || [ $? -eq 8 ] ; then  

La parte sinistra dell'OR modifica $? variabile, quindi la parte destra dell'OR non ha l'originale $? valore.


2
$ # restituisce il numero di argomenti passati allo script. Utile per verificare il corretto utilizzo. Non sembra che il richiedente stia usando i codici di uscita.
Centimane,

27

A volte è necessario utilizzare parentesi doppie, altrimenti si ottiene un errore come troppi argomenti

if [[ $OUTMERGE == *"fatal"* ]] || [[ $OUTMERGE == *"Aborting"* ]]
  then
fi

1
Questo è utile perché è l'unica cosa qui che vedo mostrare un esempio di confronti non interi, che sono leggermente diversi nella sintassi.
Christopher Hunter,

13

Se uno script bash

If [[ $input -gt number  ||  $input  -lt number  ]]
then 
    echo .........
else
    echo .........

fi

exit

7

hai provato qualcosa del genere:

if [ $# -eq 0 ] || [ $# -gt 1 ] 
then
 echo "$#"
fi

Sì. E ' echos ciao anche quando ho un singolo argomento.
Strawberry,

Il secondo $#potrebbe essere il valore di ritorno del primo test?
luckydonald,

5

Dal manuale di riferimento di Bash → 3.4.2 Parametri speciali

#
($ #) Si espande al numero di parametri posizionali in decimale.

Perciò, $# sarà sempre 0 o un numero intero più grande.

Quindi, se vuoi fare qualcosa ogni volta che $#è 0 o maggiore di 1, devi solo controllare se $#è o non è 1:

[ $# -eq 1 ] && echo "1 positional param" || echo "0 or more than 1"

Questo utilizza la sintassi:

[ condition ] && {things if true} || {things if false}

in bash puoi fare qualcosa del tipo:[[ -n $A ]] && echo 1 || echo 2
premek.v

@ premek.v grazie per il commento. La mia risposta è stata spiegata molto male, l'ho appena modificata nella speranza che facesse più luce sull'argomento.
fedorqui "SO smettere di danneggiare" il

1

E a Bash

 line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
 vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
 echo "-------->"${line1}
    if [ -z $line1 ] && [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
   fi

O in Bash

line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
echo "-------->"${line1}
   if [ -z $line1 ] || [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
  fi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.