내 crontab 스크립트가 작동하지 않는 이유는 무엇입니까?

내 crontab 스크립트가 작동하지 않는 이유는 무엇입니까?

crontab을 통해 홈 디렉토리에 저장된 스크립트를 실행하려고 하는데 작동하지 않습니다. CRON 로그는 실행될 때마다 다음과 같이 말합니다.

Sep  3 18:30:01 backup CRON[6778]: (root) CMD (/home/hannes/script > /tmp/yc.log)
Sep  3 18:30:01 backup CRON[6777]: (CRON) info (No MTA installed, discarding output)

크론탭:

*/1 * * * * /home/hannes/script > /tmp/yc.log

.sh 파일 확장자를 추가하려고 해도 아무 것도 변경되지 않습니다. yc.log 파일은 비어 있습니다.

이것은 제가 실행하려고 하는 스크립트입니다(수동으로 실행하면 제대로 작동합니다).

#!/bin/sh
cp -r -p mnt/main-nas/PATH-TO-FILE mnt/backup-nas/01/temp/server
zip -r mnt/backup-nas/01/1.19_Test.`date +%d.%m.%Y_%H.%M.%S`.zip mnt/backup-nas/01/temp/server
rm -r mnt/backup-nas/01/temp/server

도움을 주시면 감사하겠습니다! :)

답변1

귀하의 스크립트~이다실제로 실행 중인데... 어딘가에서 오류가 발생하고 있습니다. 그리고 출력을 캡처하지 않으므로 stderr은 스크립트를 로컬로 실행하는 사용자에게 stderr전송됩니다 . cron(실패도 마찬가지)

근본 원인은 다음과 같습니다. 스크립트가 stdout파일로만 리디렉션됩니다. 그러나 실패한 많은 스크립트와 프로그램은 stderr오류 메시지를 출력하는 데 사용됩니다. 실행되는 2>&1명령줄 끝에 추가하여 이를 포착해야 합니다 . 그러면 오류도 캡처되어 파일에 기록됩니다.cronstderr

이전에 이를 포착하지 못했기 때문에 stderr는 메일을 통해 다음으로 전달되었습니다 root. 하지만 로컬 전달을 위한 로컬 MTA(Mail Transfer Agent, 즉 로컬 메일 전송 프로토콜(LMTP) 서버라고도 함)가 없기 때문에 크론 오류가 발생했습니다. . 캡처를 사용하면 stderr이제 오류와 스크립트가 제대로 실행되지 않은 이유를 확인할 수 있습니다.

로그에 오류 출력이 있으면 스크립트를 추가로 디버깅하여 문제를 '수정'하기 위해 수행해야 할 작업을 결정할 수 있습니다.

답변2

그래서 여러 가지 문제가 있었습니다. 먼저 로그가 실제로 저장되도록 2>&1끝 부분을 추가하는 것을 잊었습니다 . /home/hannes/script > /tmp/yc.log두 번째로 스크립트에 오타가 있어서 모든 경로의 첫 번째 슬래시를 잊어버렸습니다. 이것 에서 home/hannes/...이것 으로 갔습니다 /home/hannes/.... 비슷한 문제를 겪고 있는 다른 사람들에게 도움이 되기를 바라며 답글을 주신 모든 분들께 감사드립니다. :)

답변3

허용된 답변은 정확하며 명시된 질문을 다루고 있습니다. 그러나 질문에 제공된 정보는 OP에 경고하는 것이 중요하다고 생각하는 이 스크립트와 관련 없는 잠재적인 문제를 나타내며 이를 올바르게 설명하는 것은 설명하기에는 너무 길기 때문에 이를 다루기 위해 특별히 답변을 추가하고 있습니다.


로깅 문제 외에도 귀하의 계약에는 잠재적으로 불쾌한 경쟁 조건이 있습니다. 스크립트는 보관할 파일을 준비하기 위해 항상 동일한 디렉터리를 사용하기 때문에 둘 이상의 스크립트 인스턴스가 동시에 실행되는 경우 첫 번째 실행에서 후속 인스턴스가 현재 작업 중인 파일을 제거하여 추가 작업이 발생할 수 있습니다. 실패 및 불완전한 아카이브일 가능성이 높습니다(파일을 zip처리하기 전에 사라지기 때문입니다).

이 문제는 두 가지 방법 중 하나로 해결될 수 있습니다. 즉, 스크립트 자체가 호출별 디렉터리를 사용해야 하거나 파일 잠금을 사용하여 동시 실행을 방지해야 합니다.

첫 번째 접근 방식은 훨씬 쉽습니다. 사용 중인 디렉터리에 날짜를 추가하기만 하면 됩니다. 이는 다음과 같습니다(이것은 또한 date한 번만 호출된다는 것을 보장합니다).

#!/bin/sh
now="$(date +%d.%m.%Y_%H.%M.%S)"
cp -r -p mnt/main-nas/PATH-TO-FILE mnt/backup-nas/01/temp/server/${now}
zip -r mnt/backup-nas/01/1.19_Test.${now}.zip mnt/backup-nas/01/temp/server/${now}
rm -r mnt/backup-nas/01/temp/server/${now}

zip파일 잠금 접근 방식은 조금 더 복잡하지만 동시에 여러 명령을 실행하여 실수로 시스템을 휩쓸지 않도록 보장하므로 더 깔끔합니다 . 여기에는 flock(이미 설치될 Ubuntu 및 Debian 패키지의 일부 ) 라는 명령을 사용하는 작업이 포함되며 util-linux다음과 같습니다(무슨 일이 일어나는지 설명하는 주석 포함).

#!/bin/sh
# All of this gets run in a subshell so we can hold a file descriptor open
# for all the commands. We're using file descriptor 9 here, but any number
# higher than 2 will work.
(
    # This flock command is what actually takes the lock. The lock itself 
    # persists until the file descriptor is closed when the subshell exits.
    # The -x means it's an exclusive lock (so only one instance can hold it).
    # The -w says to try for that many seconds before failing if something
    # else is holding the lock (this is an important safety net to ensure you
    # don’t get a long queue of these scripts waiting to run).
    # The -n indicates which file descriptor to take the lock on.
    flock -x -w 30 -n 9 || exit 1
    cp -r -p mnt/main-nas/PATH-TO-FILE mnt/backup-nas/01/temp/server
    zip -r mnt/backup-nas/01/1.19_Test.`date +%d.%m.%Y_%H.%M.%S`.zip mnt/backup-nas/01/temp/server
    rm -r mnt/backup-nas/01/temp/server
# And this line closes the subshell, and also sets the path to be used for
# the lock file by opening it as file descriptor 9 for the subshell. /run
# is generally the place you want to put stuff like this, because it will
# get cleaned up automatically every time the system reboots.
) 9> /run/backup-nas.lock

관련 정보