首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果满足某一条件,如何停止脚本中的"tail -f“并退出?

如果满足某一条件,如何停止脚本中的"tail -f“并退出?
EN

Unix & Linux用户
提问于 2023-05-31 08:35:53
回答 1查看 200关注 0票数 1

我正试图想出一个脚本来管理超级计算机上的工作。细节并不重要,但关键是脚本一旦出现就开始tail -f文件。现在,这将永远运行,但是一旦检测到任务完成,我想彻底停止它并退出脚本。

不幸的是我被困住了。我尝试了多个解决方案,但没有一个解决方案退出脚本,即使在任务被检测到退出之后,脚本也会继续运行。下面的版本似乎是最符合逻辑的版本,但这个版本也一直在运行。

我该如何处理这个问题呢?我对bash没意见,但并不是很先进。

代码语言:javascript
复制
#!/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循环运行在一个子进程中,一旦作业结束,这个循环就会杀死主进程,但是没有成功。无论哪种方式,脚本永远不会终止。

EN

回答 1

Unix & Linux用户

发布于 2023-05-31 10:14:19

由于@Paul_Pedant的评论,我设法找到了这个问题。当我在原始脚本中将tail传输到tee时,$!包含了tee的PID,而不是tail,因此只有tee会被杀死。后者得到一个$SIGPIPE,但显然它不足以阻止它。

解决方案如下:https://stackoverflow.com/a/8048493/5099168

在我的脚本中实现的相关行如下所示:

代码语言:javascript
复制
tail -f -n 100000 $outf $errf > >(tee $logf) & 
tail_pid=$!
票数 3
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/747639

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档