Estou trabalhando em um script de shell e decidi verificar meu trabalho via shellcheck.net . Consigo obter funcionalmente o mesmo comportamento das duas linhas a seguir no meu script:
findmnt /dev/sda1 >/dev/null ; if [ $? -eq 0 ]; then echo 1; else echo 0; fi
vs.
if ! findmnt /dev/sda1 >/dev/null; then echo 0; else echo 1; fi
No entanto shellcheck lança :
SC2181: Verifique o código de saída diretamente com, por exemplo, 'if mycmd;', não indiretamente com $?.
Não está imediatamente claro para mim qual usar. Eu vejo: https://github.com/koalaman/shellcheck/issues/1167 que parece ter alterado isso para vários valores possíveis. Quero ter certeza de que estou escrevendo algo que usa as melhores práticas e que será executado sem problemas e reportado com precisão.
Você só precisa usar a variável especial
$?
quando precisar de seu valor em várias invocações de outros utilitários. Por exemplo, você pode querer emiti-lo em uma mensagem de diagnóstico e depois retorná-lo de uma função. A saída de algo comprintf
seria redefinido$?
para o status de saída deprintf
, então você não seria capaz de fazerreturn "$?"
(oureturn
) diretamente depois para retornar o status de saída original. Observe que mesmo testando algo com[ ... ]
resets$?
. Você provavelmente atribuiria$?
a alguma outra variável e usaria isso.Você pode considerar usar
$?
em umaif
declaração se esse for o estilo usado no restante do projeto. Nesse caso, lembre-se de citar a expansão, pois tecnicamente$IFS
pode conter dígitos, o que significa que a expansão sem aspas de$?
potencialmente desapareceria total ou parcialmente.No entanto, isso gera muita digitação e torna o código um pouco ofuscado e um pouco desnecessariamente complicado de seguir. Observe que a invocação
utility
acima não está conectada àif
instrução que a segue de maneira imediata.Além disso, há um pouco de redundância extra aqui, já que a
if
instrução agora está examinando o status de saída do[
utilitário para testar se uma variável é zero ou não. A variável é o status de saída de outro utilitário, com o qual poderíamos ter usadoif
diretamente.Aqui fica claro que a invocação de
utility
é parte integrante daif
declaração.Veja também a lógica por trás do
SC2181
aviso no wiki ShellCheck.