En primer lugar, no soy un profesional de Bash. Descubrí hace unos meses que si uso tanto && como || operadores de cortocircuito en secuencia con llaves, entonces, en caso de que la primera declaración salga con un valor verdadero, si la última declaración en el bloque verdadero sale distinto de cero, entonces el bloque fallido también se ejecutará. Me gusta esto:
returnNumber 0 && { echo 'OK' returnNumber 1 } || { echo 'NG' }Saldrá:
OK NGEntonces, busqué la solución más fácil para esto y se me ocurrió esto:
returnNumber 0 && { echo 'OK' returnNumber 1 : } || { echo 'NG' }Lo sé, es fácil omitir el colon incorporado, pero ¿es una forma adecuada de solucionarlo?
Esto es en realidad una trampa Bash muy común. No es un error.
returnNumber 0 evalúa como verdadero, por lo que el segundo bloque (unido por lógico y && ) también se evalúa para asegurarse de que el resultado del first && second siga siendo verdadero.
El segundo bloque genera OK pero se evalúa como falso, por lo que ahora el resultado del first && second es falso. Esto significa que la tercera parte (unida por lógica o || ) también debe evaluarse, lo que hace que también se muestre NG .
En lugar de depender de && y || , deberías usar sentencias if :
if returnNumber 0; then echo 'OK' returnNumber 1 else echo 'NG' fi tl; dr: nunca use x && y || z cuando y puede devolver un estado de salida distinto de cero.
El Sr. Llama ya respondió correctamente la pregunta, esto solo para una referencia rápida de lo que sucede con las diferentes "combinaciones". El cmd0 es un "comando" con estado de salida cero y el cmd1 es distinto de cero.
cmd0() { echo -n "[$@-0]"; return 0; } cmd1() { echo -n "[$@-1]"; return 1; } second() { echo "[second]"; } doit() { echo "case: $@"; eval "$@"; echo; } doit 'cmd0 start && cmd0 first && second' doit 'cmd0 start && cmd0 first || second' doit 'cmd0 start || cmd0 first && second' doit 'cmd0 start || cmd0 first || second' doit 'cmd0 start && cmd1 first && second' doit 'cmd0 start && cmd1 first || second' doit 'cmd0 start || cmd1 first && second' doit 'cmd0 start || cmd1 first || second' doit 'cmd1 start && cmd0 first && second' doit 'cmd1 start && cmd0 first || second' doit 'cmd1 start || cmd0 first && second' doit 'cmd1 start || cmd0 first || second' doit 'cmd1 start && cmd1 first && second' doit 'cmd1 start && cmd1 first || second' doit 'cmd1 start || cmd1 first && second' doit 'cmd1 start || cmd1 first || second'produce:
case: cmd0 start && cmd0 first && second [start-0][first-0][second] case: cmd0 start && cmd0 first || second [start-0][first-0] case: cmd0 start || cmd0 first && second [start-0][second] case: cmd0 start || cmd0 first || second [start-0] case: cmd0 start && cmd1 first && second [start-0][first-1] case: cmd0 start && cmd1 first || second [start-0][first-1][second] case: cmd0 start || cmd1 first && second [start-0][second] case: cmd0 start || cmd1 first || second [start-0] case: cmd1 start && cmd0 first && second [start-1] case: cmd1 start && cmd0 first || second [start-1][second] case: cmd1 start || cmd0 first && second [start-1][first-0][second] case: cmd1 start || cmd0 first || second [start-1][first-0] case: cmd1 start && cmd1 first && second [start-1] case: cmd1 start && cmd1 first || second [start-1][second] case: cmd1 start || cmd1 first && second [start-1][first-1] case: cmd1 start || cmd1 first || second [start-1][first-1][second]