Um wrapper cron genérico que grava todas as saídas

0

Espero escrever um wrapper do cron que registre todas as saídas em uma pasta $CRON_LOG_DIR .

Seria usado como, por exemplo, segue:

* * * * * $CRON_WRAPPER "<job name>" "command"

que registraria a saída completa de stdout e stderr de command em:

$CRON_LOG_DIR/<date>/<job_name>/command_timestamp.log

Estou usando o script abaixo para $CRON_WRAPPER , no entanto, parece não registrar stdout para command quando o comando é feito de vários comandos, por exemplo

* * * * * $CRON_WRAPPER "<job name>" "command1 && command2 && command3"

Por quê?

Abaixo está o CRON_WRAPPER completo

#!/usr/bin/env zsh
COMMAND_NAME=$1
shift

DATE=$(date +%B_%d_%Y)
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)

THIS_CRON_LOG_DIR=$CRON_LOG_DIR/$DATE
mkdir -p $THIS_CRON_LOG_DIR

CRON_LOG_FILE=${THIS_CRON_LOG_DIR}/${COMMAND_NAME}_${TIMESTAMP}.log

# Joining commands:
to_join=$@
joined=$(printf ",%s" "${to_join[@]}")

# Redirecting all output to our logging file:
joined=${joined:1}">> $CRON_LOG_FILE  2>&1"

# Finally evaluating the command
eval $joined
    
por Amelio Vazquez-Reina 12.05.2015 / 02:07

1 resposta

1

Se o primeiro argumento do script for jobname e o segundo for command1 && command2 && command3 , o comando criado na variável joined será algo como

command1 && command2 && command3>> /path/to/cron/log/dir/May_12_2015/jobname_2015-05-12_01-09-25.log  2>&1

Você chama eval nessa string e ela é analisada normalmente. O redirecionamento só se aplica a 'command3.

Você deseja tratar o segundo argumento como um fragmento de shell, não como um prefixo de um fragmento de shell. Então não concatene coisas para isso. O redirecionamento pertence diretamente ao script, não sob eval , pois você está especificando-o diretamente no script e não por meio de uma string que precisa ser analisada. Tenha em atenção que o seu código seria quebrado se jobname continha qualquer caractere especial de shell, por ex. $CRON_WRAPPER $(touch /tmp/foo) stuff executaria o código touch /tmp/foo .

Outro problema com o seu script é que você está colocando vírgulas entre os argumentos se houver mais de dois, o que não faz sentido. Unir-se a eles com espaços faria mais sentido, e isso é simplesmente "$* . (Para unir-se a vírgulas como separadores, o que você fez é excessivamente complexo. Em zsh, use ${(j:,:)@} .)

Substitua a parte do script que começa por # Joining commands: por

eval "$*" >>$CRON_LOG_FILE  2>&1
    
por 12.05.2015 / 03:17