set -o pipefail errexit
impede que os comandos subseqüentes sejam executados, mas isso não ajuda, porque você não está tentando impedir que um comando subseqüente seja executado. Em um pipeline producer | consumer
, os comandos producer
e consumer
executam em paralelo . Você não pode impedir que o consumer
inicie se producer
falhar porque, salvo um acidente cronometrado, já começou.
Se as duas únicas possibilidades forem " consumer
for bem-sucedida e produzir saída não vazia" e " consumer
falhar e não produzir saída", use ifne
dos moreutils de Joey Hess .
producer | ifne consumer
No entanto, não acho que funcione no seu caso de uso - pode não haver linhas correspondentes (falso negativo e você obtém dados obsoletos), a conexão com o banco de dados pode ser perdida no meio (falso positivo e você obter dados truncados).
Se você precisa saber se o produtor foi bem-sucedido, é necessário aguardar até que seja concluído antes de iniciar o consumidor. E como o consumidor ainda não está por perto, algo precisa armazenar a saída.
Se a saída não contiver bytes nulos e não for muito grande, você poderá armazená-la em uma variável de shell.
output=$(producer); producer_status=$?
if [ $producer_status -ne 0 ]; then
echo >&2 "Producer failed with status $producer_status"
exit $producer_status
fi
printf '%s\n' "$output" | consumer
No ksh93, bash ou zsh, essa última linha pode ser simplificada para consumer <<<"$output"
.
Observe que a substituição de comandos remove novas linhas. Se as linhas vazias finais forem relevantes, uma solução alternativa é alterar a primeira linha para
output=$(producer; echo a); producer_status=$?; output=${output%?}
Se a saída for muito grande ou puder conter bytes nulos, armazene-a em um arquivo temporário.