记录所有输出的通用 cron 包装器

记录所有输出的通用 cron 包装器

我希望编写一个 cron 包装器,将所有输出记录在文件夹中$CRON_LOG_DIR

其用法如下:

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

stdout这将记录以下stderr的完整输出command

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

我正在使用下面的脚本$CRON_WRAPPER,但是,它似乎没有记录命令由多个命令组成的情况,stdout例如command

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

为什么?

下面是完整的CRON_WRAPPER

#!/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

答案1

如果脚本的第一个参数是jobname,第二个参数是command1 && command2 && command3,那么您在变量中构建的命令joined类似于

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

你调用eval这个字符串,它就会被正常解析。重定向仅适用于“command3”。

您希望将第二个参数视为 shell 片段,而不是 shell 片段的前缀。所以不要将东西连接到它上面。重定向直接属于脚本,而不是在 下eval,因为您直接在脚本中指定它,而不是通过需要解析的字符串。请注意,如果jobname包含任何 shell 特殊字符,您的代码将会中断,例如$CRON_WRAPPER $(touch /tmp/foo) stuff将执行代码touch /tmp/foo

脚本的另一个问题是,如果参数超过两个,则在参数之间添加逗号,这是没有意义的。用空格将它们连接起来会更有意义,这很简单"$*。 (对于使用逗号作为分隔符进行连接,您所做的过于复杂。在 zsh 中,请使用${(j:,:)@}。)

# Joining commands:替换脚本中以by开头的部分

eval "$*" >>$CRON_LOG_FILE  2>&1

相关内容