No bash if
, todos os status de saída diferentes de zero são tratados como falsos. Mas frequentemente (como por exemplo em grep -q
), 1 é o único status que realmente significa falso, outros indicam erros.
Posso pensar nas seguintes alternativas à planície if "${cmd[@]}"; then echo yes; else echo no; fi
:
Simplescase
#!/usr/bin/env bash
set -o errexit -o pipefail
cmd=(bash -c 'exit 10')
st=0; "${cmd[@]}" || st=$?
case $st in
(0) echo yes;;
(1) echo no;;
(*) exit $st;;
esac
Verifique se há 0 ou 1
#!/usr/bin/env bash
set -o errexit -o pipefail
cmd=(bash -c 'exit 10')
st=0; "${cmd[@]}" || st=$?
[ $st -eq 0 -o $st -eq 1 ]
if [ $st -eq 0 ]; then
echo yes
else
echo no
fi
Função auxiliar para mapear status para saída
#!/usr/bin/env bash
set -o errexit -o pipefail
# Put this somewhere for reuse:
map-status() {
local st=0
"$@" || st=$?
case $st in
(0) echo t;;
(1) echo f;;
(*) return $st;;
esac
}
cmd=(bash -c 'exit 10')
st=$(map-status "${cmd[@]}") && if [ $st = t ]; then
echo yes
else
echo no
fi
Questões
Todos eles têm o problema de serem necessários
||
após o comando check, então errexit não está ativo no comando check. (Dependendo do comando, isso pode ser corrigido com um subshell com essa opção; mas um subshell não funciona quando o comando deve definir uma variável para uso posterior.) Como isso pode ser corrigido?Existem outras maneiras concisas de escrever um careful
if
? Alguma delas talvez seja considerada a maneira idiomática?
As soluções devem funcionar com as opções errexit e pipefail habilitadas.