Por que `if $ (true); então ... fi` conseguiu?
Inspirado poressa questã:
O que uma instrução if deve fazer quando a condição é uma substituição de comando em que o comando não produz saíd
NOTA O exemplo éif $(true); then ...
, nãoif true ; then ...
Por exemplo, dado:
if $(true) ; then echo yes ; else echo no ; fi
Eu pensaria que$(true)
deve ser substituído pela saída dotrue
comando, o que não é nada. Em seguida, deve ser equivalente a isso:
if "" ; then echo yes ; else echo no ; fi
which imprimeno
porque não existe um comando cujo nome seja a string vazia ou para isso:
if ; then echo yes ; else echo no ; fi
que é um erro de sintax
Mas a experiência mostra que, se o comando não produzir saída, oif
instrução @ trata como verdadeira ou falsa, dependendo do status do comando, e não da saíd
Aqui está um script que demonstra o comportamento:
#!/bin/bash
echo -n 'true: ' ; if true ; then echo yes ; else echo no ; fi
echo -n 'false: ' ; if false ; then echo yes ; else echo no ; fi
echo -n '$(echo true): ' ; if $(echo true) ; then echo yes ; else echo no ; fi
echo -n '$(echo false): ' ; if $(echo false) ; then echo yes ; else echo no ; fi
echo -n '$(true): ' ; if $(true) ; then echo yes ; else echo no ; fi
echo -n '$(false): ' ; if $(false) ; then echo yes ; else echo no ; fi
echo -n '"": ' ; if "" ; then echo yes ; else echo no ; fi
echo -n '(nothing): ' ; if ; then echo yes ; else echo no ; fi
e aqui está a saída que recebo (Ubuntu 11.04, bash 4.2.8):
true: yes
false: no
$(echo true): yes
$(echo false): no
$(true): yes
$(false): no
"": ./foo.bash: line 9: : command not found
no
./foo.bash: line 10: syntax error near unexpected token `;'
./foo.bash: line 10: `echo -n '(nothing): ' ; if ; then echo yes ; else echo no ; fi'
As primeiras quatro linhas se comportam como eu esperava; a$(true)
e$(false)
inhas são surpreendente
Outra experiência (não mostrada aqui) indica que se o comando entre$(
e)
produz saída, seu status de saída não afeta o comportamento doif
.
Vejo comportamento semelhante (mas, em alguns casos, mensagens de erro diferentes) combash
, ksh
, zsh
, ash
edash
.
Não vejo nada na documentação do bash ou na especificação POSIX "Shell Command Language" para explicar iss
(Ou talvez esteja perdendo algo óbvio.)
EDIT: À luz da resposta aceita, aqui está outro exemplo do comportamento:
command='' ; if $command ; then echo yes ; else echo no ; fi
ou equivalente
command= ; if $command ; then echo yes ; else echo no ; fi