일반적으로 환경 설정이 없으므로 cron에서 스크립트를 실행하는 방법에 몇 가지 문제가 있습니다. cron과 동일한 방식으로 bash (?)를 호출하는 방법이 있으므로 스크립트를 설치하기 전에 테스트 할 수 있습니까?
일반적으로 환경 설정이 없으므로 cron에서 스크립트를 실행하는 방법에 몇 가지 문제가 있습니다. cron과 동일한 방식으로 bash (?)를 호출하는 방법이 있으므로 스크립트를 설치하기 전에 테스트 할 수 있습니까?
답변:
이것을 crontab에 추가하십시오 (일시적으로).
* * * * * env > ~/cronenv
실행 후 다음을 수행하십시오.
env - `cat ~/cronenv` /bin/sh
이것은 cron이 / bin / sh를 실행한다고 가정합니다. 이는 사용자의 기본 쉘에 관계없이 기본값입니다.
env -
고양이 ~ / cronenv` / 빈 / sh`은 cron 작업으로 작성해야 하는가? 예를 들어주세요
몇 가지 접근 방식 :
cron env를 내보내고 가져옵니다.
더하다
* * * * * env > ~/cronenv
crontab에 한 번 실행 한 다음 다시 끈 다음 실행하십시오.
env - `cat ~/cronenv` /bin/sh
그리고 당신은 이제 sh
cron의 환경을 가진 세션 안에 있습니다.
cron에 환경을 가져 오십시오
당신은 위의 운동을 건너 뛸 수 있고 . ~/.profile
cron 작업 앞에서 할 수 있습니다.
* * * * * . ~/.profile; your_command
화면 사용
이 개 솔루션은 여전히 그들에 접근, 실행중인 X 세션에 연결된 환경을 제공하는 것을 실패보다도 dbus
우분투에 예를 들어 등 nmcli
(네트워크 관리자) 두 가지 방법 이상에서 작동하지만 여전히 크론에 실패합니다.
* * * * * /usr/bin/screen -dm
cron에 위의 줄을 추가하고 한 번 실행 한 다음 다시 끕니다. 화면 세션에 연결하십시오 (screen -r). 화면 세션을 확인하는 경우 (함께 생성 된 ps
그들이 자본에 때때로 (예를 것을 인식) ps | grep SCREEN
)
이제는 짝수 nmcli
와 비슷한 것이 실패합니다.
당신은 실행할 수 있습니다 :
env - your_command arguments
빈 환경에서 your_command를 실행합니다.
env - HOME="$HOME" LOGNAME="$USER" PATH="/usr/bin:/bin" SHELL="$(which sh)" command arguments
트릭을 수행하는 것으로 보인다
계정의 셸에 따라
sudo su
env -i /bin/sh
또는
sudo su
env -i /bin/bash --noprofile --norc
에서 http://matthew.mceachen.us/blog/howto-simulate-the-cron-environment-1018.html
6 년 후 답변 : 환경 불일치 문제는 systemd
"타이머"가 cron 대체품으로 해결 한 문제 중 하나입니다 . CLI 또는 cron을 통해 시스템화 된 "서비스"를 실행하든 환경 불일치 문제를 피하면서 정확히 동일한 환경을 수신합니다.
cron 작업이 수동으로 전달 될 때 실패하는 가장 일반적인 문제는 $PATH
cron에서 설정 한 제한적인 기본값 이며, 이는 Ubuntu 16.04에서 발생합니다.
"/usr/bin:/bin"
대조적 으로 Ubuntu 16.04에서 $PATH
설정 한 기본값 systemd
은 다음과 같습니다.
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
따라서 시스템 타이머가 더 이상 번거 로움없이 바이너리를 찾을 가능성이 이미 높습니다.
시스템 타이머의 단점은 설정 시간이 조금 더 있다는 것입니다. 먼저 "서비스"파일을 작성하여 실행할 항목을 정의하고 "타이머"파일을 실행하여 스케줄을 정의한 후 타이머를 "활성화"하여 활성화하십시오.
env를 실행하고 stdout을 파일로 경로 재지 정하는 cron 작업을 작성하십시오. "env-"와 함께 파일을 사용하여 cron 작업과 동일한 환경을 작성하십시오.
cron의 부모는 init이므로 제어 터미널없이 프로그램을 실행한다는 것을 잊지 마십시오. 다음과 같은 도구로이를 시뮬레이션 할 수 있습니다.
기본적으로 cron
시스템의 아이디어가 무엇이든간에 작업을 실행합니다 sh
. 이것은 실제 Bourne 쉘 수 또는 수 dash
, ash
, ksh
또는 bash
(또는 다른)에 심볼릭 링크 sh
(및 POSIX 모드에서 실행 결과로).
가장 좋은 방법은 스크립트에 필요한 내용이 있는지 확인하고 아무것도 제공하지 않는다고 가정하는 것입니다. 따라서 전체 디렉토리 스펙을 사용하고 $PATH
자신 과 같은 환경 변수를 설정해야합니다 .
0 0 * * 1 /path/to/executable >/dev/null 2>&1
그런 다음 "실행 가능"내 $PATH
에서 등의 값을 설정 하고 전체 디렉토리 스펙을 사용하여 파일을 입력 및 출력하는 등의 작업을 수행합니다. 예를 들면 다음과 같습니다./path/to/do_something /another/path/input_file /another/path/to/output_file
내가 찾은 또 다른 간단한 방법 (그러나 오류가 발생하기 쉬울 수도 있지만 테스트 중임)은 명령 전에 사용자의 프로필 파일을 제공하는 것입니다.
/etc/cron.d/ 스크립트 편집 :
* * * * * user1 comand-that-needs-env-vars
로 변할 것입니다 :
* * * * * user1 source ~/.bash_profile; source ~/.bashrc; comand-that-needs-env-vars
더럽지 만 작업이 완료되었습니다. 로그인을 시뮬레이트하는 방법이 있습니까? 실행할 수있는 명령 만? bash --login
작동하지 않았다. 그래도 더 좋은 방법이 될 것 같습니다.
편집 : 이것은 확실한 해결책 인 것 같습니다 : http://www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/
* * * * * root su --session-command="comand-that-needs-env-vars" user1 -l
허용되는 답변은 cron이 사용할 환경에서 스크립트를 실행하는 방법을 제공합니다. 다른 사람들이 지적했듯이, 이것은 cron 작업을 디버깅하는 데 필요한 유일한 기준은 아닙니다.
실제로 cron은 입력 등이없는 비 대화식 터미널도 사용합니다.
그것이 도움이된다면, cron에 의해 실행될 때 명령 / 스크립트를 고통없이 실행할 수있는 스크립트를 작성했습니다. 첫 번째 인수로 명령 / 스크립트를 사용하여 호출하면 좋습니다.
이 스크립트는 Github 에서도 호스팅되고 업데이트 될 수 있습니다 .
#!/bin/bash
# Run as if it was called from cron, that is to say:
# * with a modified environment
# * with a specific shell, which may or may not be bash
# * without an attached input terminal
# * in a non-interactive shell
function usage(){
echo "$0 - Run a script or a command as it would be in a cron job, then display its output"
echo "Usage:"
echo " $0 [command | script]"
}
if [ "$1" == "-h" -o "$1" == "--help" ]; then
usage
exit 0
fi
if [ $(whoami) != "root" ]; then
echo "Only root is supported at the moment"
exit 1
fi
# This file should contain the cron environment.
cron_env="/root/cron-env"
if [ ! -f "$cron_env" ]; then
echo "Unable to find $cron_env"
echo "To generate it, run \"/usr/bin/env > /root/cron-env\" as a cron job"
exit 0
fi
# It will be a nightmare to expand "$@" inside a shell -c argument.
# Let's rather generate a string where we manually expand-and-quote the arguments
env_string="/usr/bin/env -i "
for envi in $(cat "$cron_env"); do
env_string="${env_string} $envi "
done
cmd_string=""
for arg in "$@"; do
cmd_string="${cmd_string} \"${arg}\" "
done
# Which shell should we use?
the_shell=$(grep -E "^SHELL=" /root/cron-env | sed 's/SHELL=//')
echo "Running with $the_shell the following command: $cmd_string"
# Let's route the output in a file
# and do not provide any input (so that the command is executed without an attached terminal)
so=$(mktemp "/tmp/fakecron.out.XXXX")
se=$(mktemp "/tmp/fakecron.err.XXXX")
"$the_shell" -c "$env_string $cmd_string" >"$so" 2>"$se" < /dev/null
echo -e "Done. Here is \033[1mstdout\033[0m:"
cat "$so"
echo -e "Done. Here is \033[1mstderr\033[0m:"
cat "$se"
rm "$so" "$se"
답변 https : //.com/a/2546509/5593430 은 cron 환경을 얻는 방법과 스크립트에 사용하는 방법을 보여줍니다. 그러나 사용하는 crontab 파일에 따라 환경이 다를 수 있습니다. 를 통해 환경을 저장하기 위해 세 가지 다른 cron 항목을 만들었습니다 env > log
. Amazon Linux 4.4.35-33.55.amzn1.x86_64의 결과입니다.
MAILTO=root
SHELL=/bin/bash
USER=root
PATH=/sbin:/bin:/usr/sbin:/usr/bin
PWD=/
LANG=en_US.UTF-8
SHLVL=1
HOME=/
LOGNAME=root
_=/bin/env
crontab -e
)SHELL=/bin/sh
USER=root
PATH=/usr/bin:/bin
PWD=/root
LANG=en_US.UTF-8
SHLVL=1
HOME=/root
LOGNAME=root
_=/usr/bin/env
MAILTO=root
SHELL=/bin/bash
USER=root
PATH=/sbin:/bin:/usr/sbin:/usr/bin
_=/bin/env
PWD=/
LANG=en_US.UTF-8
SHLVL=3
HOME=/
LOGNAME=root
가장 중요한 것은 PATH
, PWD
과는 HOME
다르다. 안정적인 환경에 의존하도록 cron 스크립트에서이를 설정하십시오.
나는 믿지 않는다. cron 작업을 테스트하는 유일한 방법은 나중에 1-2 분 동안 실행하도록 설정 한 다음 기다리는 것입니다.