Eu tenho um script complexo onde geralmente testo cada comando individualmente para obter sucesso. Porém, há casos em que tenho que realizar uma sequência de operações simples e prefiro obter um status de saída de toda a sequência, sem me preocupar em verificar cada comando individualmente.
Esta é minha primeira tentativa, com alguns comandos arbitrários:
#!/bin/bash
if ! (
set -e
cd test
touch foo
chown root:root foo)
then
echo "subshell failed"
else
echo "subshell completed"
fi
O set -e
objetivo era garantir que o subshell saísse com falha quando a primeira falha fosse encontrada, mas isso não funciona. Nesse caso, se o diretório test
não existir, o script simplesmente cria foo
no diretório atual e falha no arquivo chown
.
Qual é a maneira certa de fazer isso? Em outras palavras, echo 'subshell concluído' somente se todos os 3 comandos forem concluídos sem erros?
A maneira correta é verificar o status de saída de cada comando e fazer a limpeza apropriada naquele ponto. (Junto com a impressão de uma mensagem de erro apropriada, mas as próprias ferramentas provavelmente já fazem isso.) Por exemplo, se o arquivo for criado, mas as permissões não puderem ser definidas corretamente, você deseja deixar o arquivo lá ou deveria ( tentar) removê-lo?
(É verdade que este caso específico seria um pouco inesperado, mas de qualquer maneira.)
Se você não quiser ser tão sofisticado, basta dizer que deseja executar cada comando somente se o anterior for bem-sucedido, ou seja, junte-os com
&&
:Observe que isso deixaria o script em execução no diretório recém-criado. O que pode ou não ser o que você deseja fazer, dependendo do que o script fará a seguir. É claro que você ainda pode usar um subshell para isolar os efeitos de
cd
:ou simplesmente elimine
cd
totalmente:(não use
path
como nome de variável se você acha que usará zsh; isso vai explodir de forma hilariante.)De qualquer forma, esqueça
set -e
. Ele não faz o que você deseja e é confuso o suficiente para ser pior do que inútil. Veja, por exemplo, BashFAQ 105Re: https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
Ênfase minha.