저는 슈퍼컴퓨터에서 작업을 관리하기 위한 스크립트를 작성하려고 합니다. 세부 사항은 중요하지 않지만 중요한 점은 스크립트 tail -f
가 파일이 나타나면 해당 파일을 실행한다는 것입니다. 이제 이 작업은 영원히 실행되지만 작업이 완료된 것으로 감지되면 완전히 중지하고 스크립트를 종료하고 싶습니다.
불행히도 나는 붙어 있습니다. 여러 솔루션을 시도했지만 그 중 어느 것도 종료 스크립트가 없으며 작업 종료를 감지한 후에도 계속 실행됩니다. 아래 버전이 가장 논리적인 것으로 보이지만 이 버전도 영원히 실행됩니다.
이 문제를 어떻게 해결해야 합니까? 나는 bash에 익숙하지만 아직 고급 수준은 아닙니다.
#!/bin/bash
# get the path to the job script, print help if not passed
jobscr="$1"
[[ -z "$jobscr" ]] && echo "Usage: submit-and-follow [script to submit]" && exit -2
# submit job via SLURM (the job secluder), and get the
# job ID (4-5-digit number) from it's output, exit if failed
jobmsg=$(sbatch "$jobscr")
ret=$?
echo "$jobmsg"
if [ ! $ret -eq 0 ]; then exit $ret; fi
jobid=$(echo "$jobmsg" | cut -d " " -f 4)
# get the stdout and stderr file the job is using, we will log them in another
# file while we `tail -f` them (this is neccessary due to a file corruption
# bug in the supercomputer, just assume it makes sense)
outf="$(scontrol show job $jobid | awk -F= '/StdOut=/{print $2}')"
errf="$(scontrol show job $jobid | awk -F= '/StdErr=/{print $2}')"
logf="${outf}.bkp"
# wait for job to start
echo "### Waiting for job $jobid to start..."
until [ -f "$outf" ]; do sleep 5; done
# ~~~~ HERE COMES THE PART IN QUESTION ~~~~ #
# Once it started, start printing the content of stdout and stderr
# and copy them into the log file
echo "### Job $jobid started, stdout and stderr:"
tail -f -n 100000 $outf $errf | tee $logf &
tail_pid=$! # catch the pid of the child process
# watch for job end (the job id disappears from the queue; consider this
# detection working), and kill the tail process
while : ; do
sleep 5
if [[ -z "$(squeue | grep $jobid)" ]]; then
echo "### Job $jobid finished!"
kill -2 $tail_pid
break
fi
done
tail
또한 기본 프로세스에서 다른 버전을 시도했는데 while
루프가 하위 프로세스에서 실행되고 작업이 끝나면 기본 프로세스가 종료되지만 작동하지 않았습니다. 그럼에도 불구하고 스크립트는 절대 종료되지 않습니다.
답변1
@Paul_Pedant의 의견 덕분에 문제를 찾을 수 있었습니다. 원본 스크립트에서 파이핑을 했을 때 tail
포함된 PID가 없어 죽었습니다. 후자는 그것을 얻었지만 그것을 막을 만큼 충분하지 않은 것 같습니다.tee
$!
tee
tail
tee
$SIGPIPE
해결책은 아래 답변에 있습니다.https://stackoverflow.com/a/8048493/5099168
내 스크립트에 구현된 관련 줄은 다음과 같은 형식을 취합니다.
tail -f -n 100000 $outf $errf > >(tee $logf) &
tail_pid=$!