스크립트는 Y분 동안 X분마다 "if" 문을 반복하고 이것이 true가 아니면 실패합니다.

스크립트는 Y분 동안 X분마다 "if" 문을 반복하고 이것이 true가 아니면 실패합니다.

"autorep" 및 "sendevent" 명령은 Autosys에만 적용되지만 제가 실행해야 하는 스크립트는 다음과 같습니다.

if autorep -g GLOBAL_VARIABLE |grep " 0 " >/dev/null
 then 
  sendevent -E SET_GLOBAL -G "YES"

 else
  sleep 2
fi

GLOBAL_VARIABLE = 0 또는 20분(둘 중 먼저 발생하는 시간)까지 이 스크립트를 반복하려면 어떻게 해야 합니까?

for 루프를 고려하고 있지만 몇 가지 지침이 필요합니다.

autorep 명령의 출력:

Global Name                                                      Value                                                                                                Last Changed
________________________________________________________________ ____________________________________________________________________________________________________ ____________________
GLOBAL_VARIABLE                                                        Y                                                                                                    12/15/2020 00:00:01

GLOBAL_VARIABLE 값이 0이 아닌 경우 2분 동안 대기 상태로 유지한 후 다시 시도하는 스크립트가 필요합니다. 20분 종료 시점의 값이 0이 아닌 경우 스크립트는 1로 종료되어야 합니다.

답변1

이를 루프로 감싸고 while명령이 작동하는지 테스트하는 것 외에도 반복 횟수 또는 경과 시간 테스트를 추가합니다. 테스트 중인 명령이 정확하다고 가정하면 Bash 또는 표준 셸에서 작동합니다.

#!/bin/sh
elapsed=0
delay=2
timeout=$(( 20 * 60 ))
success=0
while true; do
    if autorep -g GLOBAL_VARIABLE |grep " 0 " >/dev/null; then
        success=1
        break
    fi
    if [ "$elapsed" -ge "$timeout" ]; then
        break
    fi 
    sleep "$delay"
    elapsed=$(( elapsed + delay ))
done
if [ "$success" = 1 ]; then
    echo "the command succeeded after waiting "$elapsed" seconds"
else
    echo "the command never succeeded within '$elapsed' seconds"
fi

delay단위 timeout는 초이므로 20*60 = 1200초는 20분입니다.

수면시간만을 고려한 것이므로 autorep완료하는데 시간이 많이 걸릴 경우에는 꺼지게 됩니다. Bash에서는 이를 사용하여 $SECONDS스크립트가 시작된 이후의 시간을 가져올 수 있습니다 .

또한 명령의 출력에는 올바른 위치가 아닌 한 공백으로 둘러싸인 공백이 포함될 수 없다는 것을 알고 계시겠지만 0, 예를 들어 다음을 사용하여 보다 엄격한 테스트를 수행할 수 있습니다.

... | grep -q "^GLOBAL_VARIABLE[[:space:]]*0 " 

GLOBAL_VARIABLE0으로 시작하는 줄을 확인합니다.

답변2

whilebash에서 루프를 사용하여 출력을 테스트합니다.그리고경과 시간:

#!/bin/bash
patience=$((20 * 60))
while ! autorep -g GLOBAL_VARIABLE | grep -q " 0 "  && (( SECONDS < patience ))
do
  sleep $((2 * 60))
done
if (( SECONDS >= patience ))
then
  exit 1
else
  sendevent -E SET_GLOBAL -G "YES"
fi

autorep이는 명령이 " 0 "라인을 내보내거나 경과 시간이 인내심 변수를 초과할 때까지 반복됩니다 . 이것초 변수bash는 쉘이 시작된 이후의 시간(초)으로 설정됩니다. 여기서는 새 쉘이 이 스크립트를 실행하므로 타이머처럼 작동합니다. 루프가 끝나면 시간이 경과했는지 확인합니다. 그렇다면 exit 1필요에 따라 명령을 실행합니다 sendevent.

관련 기간에 대해 가능한 한 명확한 그림을 제공하기 위해 인내 변수와 sleep 명령의 타임스탬프를 명시적으로 확장했습니다. 원래 질문에는 "sleep 2"(2초)와 "sleep 2 min"이 충돌합니다. 위의 코드는 테스트 사이에 2분 동안 잠자기 상태입니다.

답변3

GNU timeout명령을 사용하여 20분 동안 기록합니다.

if timeout 20m sh -c '
    until autorep -g GLOBAL_VARIABLE | grep -qF " 0 "; do
        sleep 120
    done'
then
    echo 'did not time out'
else
    echo 'timed out'
fi

timeout20분이 만료되면 명령은 0이 아닌 종료 상태로 종료됩니다. grep찾고 있는 문자열을 찾으면 종료 상태가 0인 상태로 종료됩니다 .

매개변수화된 수면 시간:

long_sleep=20   # minutes
short_sleep=120 # seconds

if timeout "${long_sleep}m" sh -c '
    short_sleep=$1; shift
    until autorep -g GLOBAL_VARIABLE | grep -qF " 0 "; do
        sleep "$short_sleep"
    done' sh "$short_sleep"
then
    echo 'did not time out'
else
    echo 'timed out'
fi

관련 정보