지속적으로 백그라운드 작업 예약

지속적으로 백그라운드 작업 예약

주말 동안 백그라운드에서 세 개의 SAS 프로그램이 실행 중입니다. 이 세 가지 프로그램은 동일한 이름을 가진 파일에 정보를 출력하므로 첫 번째 프로그램이 완료된 후 두 번째 프로그램이 시작되기 전, 두 번째 프로그램이 완료된 후 세 번째 프로그램이 시작되기 전에 이러한 출력 파일을 삭제해야 합니다. 분명히 이 문제를 해결하는 가장 쉬운 방법은 출력 파일 이름이 다르도록 각 프로그램을 변경하는 것이지만 Unix 사용법을 배우는 데는 도움이 되지 않습니다. 이것이 내가 지금까지 얻은 것입니다:

# Begin by running the first SAS program in the background.
sas program1.sas & | at 5:00 PM JAN 11

# I'd like to wait until the first program finishes to remove
# the output files and run the second program.
wait ???
rm file1.sas7bdat file2.sas7bdat file3.sas7bdat file4.sas7bdat file5.sas7bdat
sas program2.sas & | at 5:00 PM JAN 12

# And now I repeat.
wait ???
rm file1.sas7bdat file2.sas7bdat file3.sas7bdat file4.sas7bdat file5.sas7bdat
sas program3.sas & | at 5:00 PM JAN 13

나는 두 가지 이유로 각 프로그램을 연속적으로 동시에 실행하도록 설정했습니다. (1) 이전 프로그램이 24시간 이내에 완료된다는 것을 알고 있으며 (2) 서버의 로드가 연속적으로 비슷할 것이라고 가정합니다. 이상적으로는 어떻게든 첫 번째 프로그램의 프로세스 ID를 가져와 첫 번째 명령에 전달할 수 있고 두 번째 프로그램과 명령 wait에도 동일하게 전달할 수 있습니다 . wait어떤 아이디어가 있나요?

편집하다

wait이 특정 사례보다는 프로세스 ID를 확인하고 이를 명령에 전달하는 일반적인 솔루션에 더 관심이 있습니다.

답변1

문제는 실제로 사용해서는 안되는 작업을 수행하기 위해 at을 사용하고 있다는 것입니다. 또한 "프로그램 1 다음에 프로그램 2 실행"과 "1월 12일 오후 5시에 프로그램 2 실행"이라는 두 가지 상충되는 목표가 있습니다.

문제의 일부는 해결하기 쉽습니다. at에서는 여러 명령을 사용할 수 있습니다. 따라서 이를 사용하여 스크립트를 at예약 할 수 있을 sas뿐만 아니라 작업에 넣을 수도 있습니다 rm.

at 5:00 PM JAN 11 <<EOJ
sas program1.sas
rm file1.sas7bdat file2.sas7bdat file3.sas7bdat file4.sas7bdat file5.sas7bdat
EOJ

&대기열에 넣을 이유가 없습니다 sas. at작업은 항상 "백그라운드에서" 실행됩니다.

다음으로, 앞서 언급한 충돌을 어떻게 해결하고 싶은지 파악해야 합니다. 특히, 1월 11일 작업이 24시간 이후(1월 12일 오후 5시까지)까지 완료되지 않은 경우. 이 문제를 해결하는 방법에는 여러 가지가 있습니다.

  • 이건 1월 12일의 일이 아닙니다. program1.sas가 완료된 후 즉시 실행되어야 합니다. 이 경우에는 위의 첫 번째 할당의 일부로 만드세요 rm.
  • 이런 일은 결코 일어나지 않을 것입니다. 그렇다면 수동으로 수정합니다. 이런 경우에는 위와 같이 정리하면 됩니다.
  • 기다려야합니다. 이 경우 첫 번째 작업이 끝날 때 예약하거나 잠금 파일을 사용하거나 적절한 절전 시간을 계산할 수 있습니다(또는 sleepenh직접 계산을 수행하지 않으려면 사용 가능한 경우 를 사용하세요).

답변2

따라서 해야 할 일과 하고 싶은 일은 기본적으로 다음과 같이 요약됩니다.

command1 &
wait <on command1>
sleep <until specified time>

command2 &
wait <on command2>
sleep <until specified time>

...

이 경우 배경( &)과 wait및 를 제거하면 sleep명령이 순차적으로 실행됩니다. 그러나 이로 인해 즉시 실행됩니다.

특정 시간까지 기다리려면 sleep적절한 시간을 기다리면 됩니다. sleep입력에는 몇 초가 걸리며 Unix 시스템은 전통적으로 몇 초 단위로 시간을 저장하고 측정하므로 이는 간단한 산술로 요약됩니다.

  1. 대기 날짜와 시간을 에포크 이후의 초 단위로 변환합니다.
  2. 현재 시간을 에포크 이후의 초로 변환합니다.
  3. 차이를 계산해 보세요.
  4. 너무 오래 자요.

이 작업을 수행하는 방법이 스택 오버플로 답변, 그러나 중요한 부분을 복사하십시오.

current_epoch=$(date +%s)
target_epoch=$(date -d '01/01/2010 12:00' +%s)
sleep_seconds=$(( $target_epoch - $current_epoch ))
sleep $sleep_seconds

이 특정 예는 bash 구문으로 되어 있지만 모든 쉘 스크립팅 언어로 쉽게 변환되어야 합니다. $(...)명령을 실행하고 해당 명령의 출력을 바꾸고 $(( ... ))산술 표현식을 평가합니다.

GNU는 또한 시간 전용 타임스탬프를 지원하므로 이를 다가오는 05:00으로 변환한다고 date -d말할 수 있습니다 .date -d '05:00'

이것을 종합하면 원하는 스크립트를 쉽게 만들 수 있습니다.

답변3

글쎄요, 순서는 없습니다 wait. 적어도 내가 아는 한은 아니다. 내 대체 논리는 다음과 같습니다.

각 SAS 프로그램에 대해 3개의 스크립트 파일을 만듭니다. 이러한 스크립트는 이전 sas 프로그램의 실행이 완료된 후에만 실행됩니다. pid이전 sas 프로그램을 캡처하고 ps명령을 사용하여 출력 파일을 삭제하기 전에 해당 프로그램이 더 이상 실행되지 않는지 확인하면 됩니다 .

crontab매주 금요일부터 일요일까지 스크립트가 실행되도록 예약합니다 .

따라서 첫 번째 스크립트 파일의 이름을 지정하면 sas_script1.sh다음과 같습니다.

if [ -f /var/run/sas.pid ]; then
    /bin/ps $( cat /var/run/sas.pid ) >/dev/null
    [ $? ] && exit               #  $? checks the exit status of the last command
fi

rm -f /path/to/file{1..5}.sas7bdat

/usr/bin/sas /path/to/program1.sas &

echo $! >/var/run/sas.pid       #  $! gives you the PID of the last program that's sent background

두 SAS 프로그램의 나머지 부분에 대해 동일한 스크립트를 작성합니다. 예를 들어 다음 program1.sas과 같이 편집합니다.program2.sas

하나를 만들고 file그 안에 다음 내용을 작성합니다.

00 17 * * 5 /path/to/sas_script1.sh
00 17 * * 6 /path/to/sas_script2.sh
00 17 * * 0 /path/to/sas_script3.sh

이제 파일을 cron 작업으로 업로드합니다.

crontab /path/to/file

Un*X에 대해 더 자세히 알아볼 수 있습니다. :D

관련 정보