cron이 수동으로 호출하지 않고 스크립트를 시작했는지 확인 cron이 프로그램을 실행할 때

cron이 프로그램을 실행할 때 설정하는 변수가 있습니까? 스크립트가 cron에 의해 실행되면 일부 부분을 건너 뛰고 싶습니다. 그렇지 않으면 해당 부분을 호출하십시오.

Bash 스크립트가 cron에 의해 시작되었는지 어떻게 알 수 있습니까?



답변

나는 cron그것이 환경에서 기본적으로 여기에서 사용할 수있는 일을 알고 있지만, 원하는 효과를 얻기 위해 할 수있는 몇 가지가 있습니다.

1) 하드 또는 소프트 있도록 스크립트 파일에 대한 링크, 예를 들어, 확인 myscriptmyscript_via_cron같은 파일을 가리키고. 그런 다음 $0코드의 특정 부분을 조건부로 실행하거나 생략 할 때 스크립트 내부 의 값을 테스트 할 수 있습니다 . crontab에 적절한 이름을 입력하면 설정됩니다.

2) 스크립트에 옵션을 추가하고 crontab 호출에서 해당 옵션을 설정하십시오. 예를 들어, -c스크립트가 코드의 해당 부분을 실행 또는 생략하도록 지시하고 -ccrontab의 명령 이름에 추가 하도록 옵션을 추가 하십시오.

물론 cron 임의의 환경 변수를 설정할 있으므로 RUN_BY_CRON="TRUE"crontab 과 같은 줄을 넣고 스크립트에서 그 값을 확인할 수 있습니다.


답변

cron에서 실행되는 스크립트는 대화식 쉘에서 실행되지 않습니다. 시작 스크립트도 아닙니다. 차이점은 대화식 쉘에는 tty에 STDIN 및 STDOUT이 첨부되어 있다는 것입니다.

방법 1 : 플래그 가 $-포함되어 있는지 확인하십시오 i. i대화식 쉘에 설정됩니다.

case "$-" in
    *i*)
        interactive=1
        ;;
    *)
        not_interactive=1
        ;;
esac

방법 2 : 확인 $PS1이 비어 있습니다.

if [ -z "$PS1" ]; then
    not_interactive=1
else
    interactive=1
fi

참조 : http://techdoc.kvindesland.no/linux/gnubooks/bash/bashref_54.html

방법 3 : tty를 테스트하십시오. 아니에요 으로 신뢰할 수있는,하지만 크론 스크립트에 청각 장애를 할당 기본적으로하지 않는 간단한 cron 작업에 대한 당신은 확인해야합니다.

if [ -t 0 ]; then
    interactive=1
else
    non_interactive=1
fi

그러나를 사용하여 대화식 쉘을 강제 실행할 수는 있지만 -i이 작업을 수행하고 있는지 알고있을 것입니다.


답변

먼저 cron의 PID를 얻은 다음 현재 프로세스의 상위 PID (PPID)를 가져 와서 비교하십시오.

CRONPID=$(ps ho %p -C cron)
PPID=$(ps ho %P -p $$)
if [ $CRONPID -eq $PPID ] ; then echo Cron is our parent. ; fi

스크립트가 cron에 의해 시작되었을 수있는 다른 프로세스에 의해 시작된 경우 $ CRONPID 또는 1 (초기 PID)에 도달 할 때까지 상위 PID를 백업 할 수 있습니다.

다음과 같이, 아마도 (테스트되지 않은-하지만-그것은-일 <TM>) :

PPID=$$   # start from current PID
CRON_IS_PARENT=0
CRONPID=$(ps ho %p -C cron)
while [ $CRON_IS_PARENT -ne 1 ] && [ $PPID -ne 1 ] ; do
  PPID=$(ps ho %P -p $PPID)
  [ $CRONPID -eq $PPID ] && CRON_IS_PARENT=1
done

Deian : RedHat Linux에서 테스트 된 버전입니다

# start from current PID
MYPID=$$
CRON_IS_PARENT=0
# this might return a list of multiple PIDs
CRONPIDS=$(ps ho %p -C crond)

CPID=$MYPID
while [ $CRON_IS_PARENT -ne 1 ] && [ $CPID -ne 1 ] ; do
        CPID_STR=$(ps ho %P -p $CPID)
        # the ParentPID came up as a string with leading spaces
        # this will convert it to int
        CPID=$(($CPID_STR))
        # now loop the CRON PIDs and compare them with the CPID
        for CRONPID in $CRONPIDS ; do
                [ $CRONPID -eq $CPID ] && CRON_IS_PARENT=1
                # we could leave earlier but it's okay like that too
        done
done

# now do whatever you want with the information
if [ "$CRON_IS_PARENT" == "1" ]; then
        CRON_CALL="Y"
else
        CRON_CALL="N"
fi

echo "CRON Call: ${CRON_CALL}"

답변

스크립트 파일이 호출되고 cron첫 번째 행에 쉘이 포함되어 #!/bin/bash있으면 목적에 따라 부모-부모 이름을 찾아야합니다.

1) cron주어진 시간에 호출되어 crontab쉘을 실행합니다. 2) 쉘이 스크립트를 실행합니다. 3) 스크립트가 실행 중입니다.

부모 PID는 bash에서 variable로 사용할 수 있습니다 $PPID. ps명령은 PID가 부모의 부모의 PID를 얻을 수 있습니다 :

PPPID=`ps h -o ppid= $PPID`

그러나 우리는 pid가 아닌 명령의 이름이 필요합니다.

P_COMMAND=`ps h -o %c $PPPID`

이제 “cron”에 대한 결과 만 테스트하면됩니다.

if [ "$P_COMMAND" == "cron" ]; then
  RUNNING_FROM_CRON=1
fi

이제 스크립트의 어느 곳에서나 테스트 할 수 있습니다

if [ "$RUNNING_FROM_CRON" == "1" ]; then
  ## do something when running from cron
else
  ## do something when running from shell
fi

행운을 빕니다!


답변

FreeBSD 또는 Linux에서 작동합니다 :

if [ "Z$(ps o comm="" -p $(ps o ppid="" -p $$))" == "Zcron" -o \
     "Z$(ps o comm="" -p $(ps o ppid="" -p $(ps o ppid="" -p $$)))" == "Zcron" ]
then
    echo "Called from cron"
else
    echo "Not called from cron"
fi

원하는만큼 프로세스 트리를 올라갈 수 있습니다.


답변

“내 출력이 터미널입니까 아니면 스크립트에서 실행되고 있습니까?”라는 질문에 대한 일반적인 해결책은 다음과 같습니다.

( : > /dev/tty) && dev_tty_good=y || dev_tty_good=n

답변

echo $TERM | mail me@domain.comcron 의 간단한 것은 Linux와 AIX 모두에서 cron이$TERM 이 ‘dumb’ 되어있는 .

이제 이론적으로 여전히 실제 바보 같은 터미널이있을 수 있지만 대부분의 경우 충분하다고 생각합니다 …