직접 호출하면 잘 작동하지만 cron으로 실행하면 실패하는 비교적 간단한 bash 스크립트가 있습니다. 이것이 실패하는 이유는 무엇이며 cron을 통해 작동하게 하려면 어떻게 해야 합니까?
#!/bin/bash
apt-get update -y
apt-get upgrade -y
apt-get install boinc-client -y
cron이 이를 실행하려고 시도한 후 수동으로 호출하면 다음 오류가 발생합니다.
dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.
그러나 처음 수동으로 실행하는 한 정상적으로 작동합니다.
답변1
이러한 유형의 질문에 대한 일반적인 대답은 cron 작업이 비대화형, 비로그인 셸에서 실행되므로 대부분의 셸 시작 파일(시스템 전체 파일 /etc
과 홈 디렉터리의 개인 도트 파일 모두)이 소스가 아니라는 것입니다( 읽고 실행됨), 대부분의 쉘 시작 파일은 로그인 쉘(컴퓨터에 로그인할 때 표시되는 첫 번째 쉘) 또는 대화형 쉘(사용자가 로그인하기 때문에 터미널, SSH 세션 또는 터미널 에뮬레이터에 연결되는 쉘)에 적용되기 때문입니다. 해당 터미널을 통해 그들과 상호 작용합니다).
따라서 일반적으로 , , 또는 PATH
와 같은 위치에서 발생하는 일부 환경 설정(변경 포함)에 실제로 의존하는 크론 작업에 명령을 입력하면 해당 설정은 크론 작업에 대해 발생하지 않습니다. cron 파일 형식을 사용하면 작업에 대한 환경 변수를 지정할 수 있으므로 소스에 대한 셸 시작 스크립트에서 이를 지정 하거나 가리킬 수 있습니다. 매뉴얼 페이지 의 "호출" 섹션을 참조하십시오 ./etc/profile
/etc/bashrc
~/.profile
~/.bashrc
BASH_ENV
ENV
bash(1)
답변2
이것은 답변의 자격이 없지만 논평할 수는 없습니다. 제안:
bash 스크립트 앞에 다음을 추가하십시오. 메일 출력에 기록된 마지막 줄은 실패한 명령이 됩니다.
set -x set -e
postfix
sendmail이 있는지 확인하십시오( 또는 같은 제공 패키지 설치esmtp
).- 메일 리더 설치(권장
mutt
) - 메일이 당신에게 도착했는지 확인하세요
- postfix를 통해(설치 프로그램에 의해 자동으로 수행될 수 있음):
root: my-user-name
추가/etc/aliases
또는/etc/postfix/aliases
- cron을 통해:
MAILTO="my-user-name"
적절한crontab
파일 에 추가
- postfix를 통해(설치 프로그램에 의해 자동으로 수행될 수 있음):
스크립트가 다른 환경에서 실행되는지 확인합니다. apt-get에 대한 전체 경로를 지정하고(apt-get이 발견된 것으로 알려졌으므로 범인이 아닐 수도 있음) X 외부의 콘솔(터미널이 아님)에서 실행합니다(일부 dpkg 구성 스크립트에는 X 세션이 필요함).
- 절대 경로를 사용하도록 스크립트를 수정합니다. 즉,
/usr/bin/apt-get update -y
(올바른 경로로 교체) - 눌러서 콘솔로 전환
ctrl-alt-f1
- 루트 사용자로 전환:
sudo -i
- 환경 없이 비로그인 쉘을 시작하십시오:
env -i /bin/bash --noprofile --norc
(올바른 경로로 바꾸십시오) - 스크립트를 실행하십시오:
/my/full/path/to/cronscript
. 작동합니까?
- 절대 경로를 사용하도록 스크립트를 수정합니다. 즉,
스크립트에 권한이 있습니까? 시스템 crontab을 사용하고 있습니까? (다시 한번 말씀드리지만 범인은 아닐 가능성이 높습니다)
- 시스템 crontab을 사용한다고 밝혔으므로 이 부분은 건너뜁니다.
apt-get에는 세션 지원(consolekit 또는 systemd)이 필요합니까? 그러나 이것은 단지 어둠 속에서의 촬영일 뿐입니다.
- 도움이 될 만큼 지식이 부족합니다.
답변3
무슨 일이 일어나고 있는지 거의 이해하지 못한 채 문제를 해결했습니다. 루트 crontab에서 실행 중이더라도 apt-get 명령 앞에는 여전히 sudo가 필요하다는 것이 밝혀졌습니다. 논리적으로 나는 스크립트가 이미 "루트로" 실행 중이므로 필요하지 않을 것이라고 예상했지만 sudo를 추가하면 모든 것이 예상대로 정확하게 작동했습니다.