Eu pensei
[ 1 -eq $1 ] && echo "yes" || echo "no"
Age como
if [ 1 -eq $1 ]; then
echo "yes"
else
echo "no"
fi
Mas, quando eu executo este script ( nocmd
é um comando inexistente)
#!/bin/bash
[ 1 -eq $1 ] && nocmd "yes" || echo "no"
Eu recebo uma saída estranha para o parâmetro '1':
me@ubuntu:/tmp$ ./ddd.sh 0
no
me@ubuntu:/tmp$ ./ddd.sh 1
./sh.sh: line 3: nocmd: command not found
no
Parece que ele age como:
if [ 1 -eq $1 ]; then
nocmd "yes"
if [ $? -ne 0 ]; then
echo "no"
fi
else
echo "no"
fi
Está bom? Estou esquecendo de algo?
Exceto pelo status geral de saída, ele age como:
Dentro:
B
é executado seA
falhar. Isso é um operador OU.No seu caso,
A
é[ 1 -eq $1 ] && nocmd "yes"
ondenocmd
é executado se[
for bem-sucedido (um operador AND), caso em que o status de saídaA
será o denocmd
. Em outras palavrasecho no
, será executado se[
ounocmd "yes"
falhar (lembrando quenocmd
só é executado se for bem-[
sucedido).Esses
x && y || z
são hacks sujos. É melhor evitá-los exatamente por esse motivo. Use uma construçãoif
// se quiser uma lógica if/then/elsethen
.else
Usex && y || z
apenas se você quiser , a menos quez
ambos tenham sucesso.x
y
Mesmo em:
O
echo OK
pode falhar em algumas condições patológicas (como stdout indo para um arquivo em um sistema de arquivos completo) eecho >&2 KO
pode acabar sendo executado também.Bem, o que realmente acontece é isso (e é assim que
&&
funciona||
)No seu caso, se
$1
não for igual a1
, ou não for um número válido , então você tem um diferente de zero$?
, e o primeiroif
é ignorado e o segundoif
imprime "não". Se$1
igual1
a , entãonocmd "yes"
é executado, retornando um diferente de zero$?
e "não" também é repetido.O que está faltando é isso
&&
e||
operar no status de saída dos comandos à esquerda deles - associatividade à esquerda. Você tem aquisome group of commands || echo "no"
, eno
será repetido se e somente se esse grupo de comandos retornar o status de saída sem sucesso.O que é esse grupo de comandos? No primeiro caso você tem
[ 1 -eq "$1" ] && echo "yes"
. Se[
parte falhou, isso seria contado como status de saída de falha para[ 1 -eq "$1" ] && echo "yes"
, portanto, vocêecho "no"
executaria. Também por causa da associatividade à esquerda, quando "$ 1" é 1, o[ 1 -eq $1 ]
retorno é sucesso, então vamosnocmd
executar o que não existe e o shell retornará o status de saída de erro, todo o grupo terá status de saída de falha, portanto "não" é ecoado .Por outro lado, em sua declaração if
qual rota tomar depende apenas do status de saída da
[
parte. Em[ 1 -eq "$1" ] && echo "Yes" || echo "no"
eco também desempenha um papel sobre se éecho "no"
executado ou não.Seu segundo exemplo de instrução if também é diferente
O
echo "no"
depoiselse
não depende do que acontecenocmd
como no encadeamento de operadores lógicos. Claro que você ainda faz aecho "no"
parte depois de fazernocmd
, mas aqui seu status de saída não é agrupado com toda aif
parte à qual pertence.