Cómo hacer una operación OR lógica en scripting de shell

571

Estoy tratando de hacer una simple verificación de condición, pero no parece funcionar.

Si $#es igual 0o mayor que 1entonces diga hola.

He intentado la siguiente sintaxis sin éxito:

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

if [ "$#" == 0 ] || [ "$#" > 1 ] ; then
 echo "hello"
fi
fresa
fuente
Ambos trabajan para mí. ¿Especificó un shell en la línea shebang ?
Jason McCreary el
1
@ Jason De hecho, olvidé la línea shebang, pero la probé hace un momento y no funcionó.
Fresa
25
>es la redirección de salida en sh / bash. Ahora probablemente tenga un archivo llamado 1.
mark4o
Para obtener información sobre las comparaciones de Bash, consulte mis respuestas a preguntas anteriores aquí y aquí . Para obtener información adicional sobre paréntesis, paréntesis dobles y paréntesis dobles, consulte mi respuesta aquí .
Pausado hasta nuevo aviso.
No funciona porque escribes mal la compra: usa "$ #" == "0" o $ # -eq 0
ETech

Respuestas:

987

Esto debería funcionar:

#!/bin/bash

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

No estoy seguro de si esto es diferente en otros shells, pero si desea usar <,>, debe ponerlos entre paréntesis dobles de la siguiente manera:

if (("$#" > 1))
 ...
Distrito de codificación
fuente
2
No estoy seguro de si es diferente en otro shell pero en bash, si desea usar> o <, debe ponerlos entre paréntesis dobles de la siguiente manera: (("$ a" <"$ b"))
Codificación Distrito
1
@Doug: No es que Unix no los use, es ese bash y todos los otros shells que conozco los usan para la redirección de entrada / salida.
Cascabel el
56

Este código me funciona:

#!/bin/sh

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

No creo que sh sea compatible con "==". Use "=" para comparar cadenas y -eq para comparar entradas.

man test

para más detalles.

jbremnant
fuente
¿Cuál es la opción para mayor que? ¿Dónde está la documentación oficial para tihs?
Fresa
3
Debería ser -gtmayor que. O simplemente reemplácelo todo con [ $# -ne 1 ].
mark4o
Mayor que es -gt, mira mi respuesta. La documentación oficial está en prueba de hombre como ha señalado jbremnant.
Coding District
Igual que para otros, dependiendo de su shell, la mayoría admite == (ahora unos días) como operador de comparación, sin embargo, la mayoría de las veces es lo mismo que el operador =. Me imagino que si está usando -gt y -ne para las comparaciones, sería una mejor práctica usar -eq para == o = para mantener su estilo de script consistente. Happy Bashing :)
jkdba
34

Si está utilizando el estado del código de salida bash $? como variable, es mejor hacer esto:

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

Porque si lo haces:

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

La parte izquierda del OR altera el $? variable, entonces la parte derecha del OR no tiene el $ original ? valor.

luca76
fuente
2
$ # devuelve el número de argumentos pasados ​​al script. Útil para verificar el uso correcto. No parece que el autor de la pregunta esté usando códigos de salida.
Centimane
27

A veces necesita usar corchetes dobles, de lo contrario, obtendrá un error como demasiados argumentos

if [[ $OUTMERGE == *"fatal"* ]] || [[ $OUTMERGE == *"Aborting"* ]]
  then
fi
TechNikh
fuente
1
Esto es útil porque es lo único que veo aquí que muestra un ejemplo de comparaciones no enteras, que son ligeramente diferentes en sintaxis.
Christopher Hunter
13

Si un script bash

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

fi

exit
Peprah David
fuente
7

Has intentado algo como ésto:

if [ $# -eq 0 ] || [ $# -gt 1 ] 
then
 echo "$#"
fi
John Boker
fuente
Sí tengo. Es echohola incluso cuando tengo un solo argumento.
Fresa
¿El segundo $#podría ser el valor de retorno de la primera prueba?
luckydonald
5

Del Manual de referencia de Bash → 3.4.2 Parámetros especiales

#
($ #) Se expande al número de parámetros posicionales en decimal.

Por lo tanto, $#siempre será 0 o un número entero mayor.

Entonces, si desea hacer algo siempre $#que sea 0 o mayor que 1, solo debe verificar si $#es o no 1:

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

Esto usa la sintaxis:

[ condition ] && {things if true} || {things if false}
fedorqui 'así que deja de dañar'
fuente
en bash puedes hacer algo como:[[ -n $A ]] && echo 1 || echo 2
premek.v
@ premek.v gracias por el comentario. Mi respuesta fue muy mal explicada, solo la edité con la esperanza de que arroje más luz sobre el tema.
fedorqui 'SO deja de dañar'
1

Y en 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 en 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
Ravi Tyagi
fuente