Um pipe executa os dois lados em paralelo. A maneira como você está tentando fazer isso é conceitualmente impossível: você não pode testar o status do comando mysqldump até que ele seja concluído se você fizer esse teste em paralelo com a execução de mysqldump . Você precisa executar mysqldump , esperar que ele termine e então decidir se deseja executar gzip .
Como mysqldump precisa terminar a execução, sua saída precisa ir para algum lugar. Provavelmente você espera que a saída seja grande, já que você está comprimindo. Portanto, a opção sensata é comprimi-lo. Então, comprima a saída incondicionalmente.
mysqldump -u username -ppassword dbname | gzip > test.gz
Observe que usei | , não |& . Usar |& aqui não faz sentido: se houver alguma mensagem de erro, eles acabarão misturados com o dump e seria impossível restaurar o dump.
O problema que ainda precisa ser resolvido é detectar se mysqldump foi bem-sucedido. Supondo que este seja um script bash ou ksh (ou seja, ele começa com #!/bin/bash ou #!/bin/ksh ou algo semelhante, não com #!/bin/sh ), defina o pipefail , para que o pipeline falhe se alguma parte falhar. (Por padrão, o status de um pipeline é o status de seu comando mais à direita e o status dos outros comandos é ignorado.)
#!/bin/bash
set -o pipefail -o errexit
tmp="mydump.tmp.$$.gz"
trap 'rm -f "$tmp"' ERR INT TERM HUP
mysqldump … | gzip >"$tmp"
mv "$tmp" mydump.gz
Definir a opção errexit garante que, se o pipeline falhar, o script saia nesse ponto (com o mesmo status de erro do pipeline). Assim, um arquivo chamado mydump.gz é criado apenas se o dump foi bem-sucedido. O comando trap configura uma interceptação para que, se o script falhar ou for eliminado por um dos sinais listados, o arquivo temporário seja excluído.