모든 출력을 기록하는 일반 크론 래퍼

모든 출력을 기록하는 일반 크론 래퍼

모든 출력을 폴더에 기록하는 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"에서만 작동합니다.

두 번째 인수를 쉘 조각의 접두사가 아닌 쉘 조각으로 처리하려고 합니다. 그러니 그것에 연결하지 마십시오. 리디렉션은 eval구문 분석해야 하는 문자열을 통하지 않고 스크립트에서 직접 지정하므로 아래가 아닌 스크립트에 직접 속합니다. 셸 특수 문자를 포함 하면 jobname코드가 중단됩니다. 예를 들어 $CRON_WRAPPER $(touch /tmp/foo) stuff코드가 실행됩니다 touch /tmp/foo.

스크립트의 또 다른 문제점은 매개변수가 2개 이상일 경우 매개변수 사이에 쉼표가 추가된다는 점입니다. 이는 의미가 없습니다. 공백으로 연결하는 것이 더 합리적일 것입니다 "$*. 간단합니다 . (지금 하고 있는 작업은 쉼표를 구분 기호로 사용하여 연결하기에는 지나치게 복잡합니다. zsh에서는 ${(j:,:)@}.)

# Joining commands:다음으로 시작하는 스크립트 부분을 바꿉니다.

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

관련 정보