Ter saída de email cron para MAILTO com base no status da saída

11

Eu tenho um trabalho cron executando um comando php como este:

php /path/to/script.php > dev/null

Isso deve enviar apenas a saída STDERR para o endereço MAILTO. Pelo que pego, o script php não está exibindo nenhuma informação STDERR, mesmo quando seu status de saída é 1.

Como posso obter a saída do comando php (STDOUT) e enviá-la apenas para MAILTO se o status de saída for diferente de zero?

Dave
fonte

Respostas:

12
php /path/to/script.php > logfile || cat logfile; rm logfile

que despeja a saída padrão logfilee a gera somente se o script falhar (sai diferente de zero).

Nota: se o seu script também pode gerar saída stderr, você deve redirecionar stderrpara stdout. Caso contrário, qualquer coisa impressa stderrfará com que o cron envie um email, mesmo que o código de saída seja 0:

php /path/to/script.php > logfile 2>&1 || cat logfile; rm logfile
Kyle Jones
fonte
Isso também será exibido para qualquer coisa que apareça no stderr, o que não significa necessariamente que haja um erro (por exemplo, saída de depuração).
Hoffmanc
3

Já considerou crônica de moreutils . Eu acho que faz exatamente o que você quer:

chronic executa um comando e organiza a saída padrão e o erro padrão a serem exibidos apenas se o comando falhar (sai diferente de zero ou trava). Se o comando for bem-sucedido, qualquer saída estranha será ocultada.

Nas revisões recentes, existe uma -eopção para mostrar também a saída completa se algo tiver sido gravado no stderr.

saraedum
fonte
2

Como a saída é gerada antes que o status de saída seja conhecido, você precisará armazená-la em algum lugar.

Uma possibilidade é armazená-lo em uma variável de shell:

output=$(php /path/to/script.php)
if [ $? -ne 0 ]; then
  printf "%s\n" "$output"
fi

Isso não preserva completamente a saída do script (remove as linhas em branco à direita), mas tudo bem para este caso de uso. Se você deseja preservar as linhas em branco à direita:

output=$(php /path/to/script.php; ret=$?; echo a; exit $ret)
if [ $? -ne 0 ]; then
  printf "%s" "${output%a}"
fi

Se houver potencialmente muita saída, você pode preferir armazená-la em um arquivo temporário:

output_file=$(mktemp /var/tmp/script.XXXXXXXXXX.out)
php /path/to/script.php >>"$output_file"
ret=$?
if [ $ret -ne 0 ]; then
  echo "script.php failed (status $ret), see the output in $output_file"
fi
Gilles 'SO- parar de ser mau'
fonte