bash si pregunta de comportamiento de declaración

bash si pregunta de comportamiento de declaración

Escribí el siguiente fragmento de script bash.

if [ $(tmux has -t junk) ]
then
echo zero
else
echo one
fi

Siempre devuelve uno, sin importar si la sesión existe o no. Verifiqué la línea de comando ejecutando la instrucción tmux y luego ejecutando $? . Se comporta como se esperaba, cero si existe la sesión y uno si no existe la sesión. ¿Por qué no lo es si la declaración no se comporta de la misma manera? Intenté cambiar la declaración if como se muestra a continuación

tmux has -t junk
if [ $? -eq 0 ]
then
echo zero
else
echo one
fi

Lo anterior funciona. Entonces, ¿qué hay de malo con el primer bloque de declaraciones?

Respuesta1

Como se mencionó, if [ $(tmux has -t junk) ]expanda a lo if [ ]que se evalúa como falso.

Podrías usar:

if tmux has -t junk; then
    echo OK
else
    echo ERR
fi

O si quieres el más corto:

tmux has -t junk || echo ERR

O

tmux has -t junk && echo OK || echo ERR

También puedes negarlo si es más adecuado, como en:

! tmux has -t junk || echo OK
! tmux has -t junk && echo ERR || echo OK
etc.

Editar:

Tampoco es que si un comando produce un resultado, es posible que desees redirigir ese resultado al agujero negro como /dev/nullen:

 if my_cmd >/dev/null; then echo OK else; echo ERR; fi

Si el comando produce un error de texto, es posible que también desee redirigir el error estándar de la siguiente manera:

 if my_cmd >/dev/null 2>&1; then echo OK else; echo ERR; fi

Es posible que ya conozca bien lo que sigue, pero agréguelo para que esté un poco más completo.

Como se mencionó: $?es la única forma de obtener el valor de retorno del programa.

Algunos programas varían en rendimiento y pueden tener un significado bastante explícito.

Entonces, por ejemplo:

mycmd
ecode=$?

case "$ecode" in
0) echo "Success";;
1) echo "Operation not permitted";;
2) echo "No such file or directory";;
esac

De este modo se pueden tomar las medidas adecuadas ante errores específicos.

Si tiene MySQL instalado, puede hacer esto, por ejemplo, medianteperror:

for i in {0..50}; do perror $i; done
# And
for i in {1000..1050}; do perror $i; done

para tener una idea de ello.

Ver tambiénesta respuestarelacionado con errores específicos del sistema operativo que también enlaza con el documento de Grupos abiertosNúmeros de erroryerrno.h.

O echa un vistazo aSQLitey eslos extendidos.

Respuesta2

Cuando usas:

if [ $(tmux has -t junk) ]

Esto verifica la salida del comando tmux has -t junkpero no el valor de retorno.

Entonces, dado que siempre imprime uno como en el primer caso, esto significa que el tmux has -t junkcomando no imprime nada en la salida estándar.

Entonces, en el primer caso,

if [ $(tmux has -t junk) ] 

está siendo evaluado como

if [ ]

información relacionada