일반적으로 환경 설정이 없으므로 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
그리고 당신은 이제 shcron의 환경을 가진 세션 안에 있습니다.
cron에 환경을 가져 오십시오
당신은 위의 운동을 건너 뛸 수 있고 . ~/.profilecron 작업 앞에서 할 수 있습니다.
* * * * * . ~/.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 작업이 수동으로 전달 될 때 실패하는 가장 일반적인 문제는 $PATHcron에서 설정 한 제한적인 기본값 이며, 이는 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 분 동안 실행하도록 설정 한 다음 기다리는 것입니다.