Unix系统中如何查看由脚本启动的运行中作业?
为什么通过管道+sh执行的后台作业用jobs看不到?
这事儿我之前也碰到过!核心原因很简单:你用sed ... | sh的时候,管道右边的sh是一个独立的子shell进程,它和你当前操作的shell完全是两个不同的会话。而jobs命令只能追踪当前shell会话里启动的后台作业,子shell里跑的后台进程根本不属于当前shell的作业列表,所以自然看不到啦。
给你几个实用的解决办法:
方法1:用source在当前shell执行生成的命令
先把sed生成的命令保存成一个临时脚本,然后用source(或者.)让当前shell直接执行它,这样后台作业就属于当前会话了:
# 把sed输出写入临时脚本 sed 's/\(.*\)\t\(.*\)/ echo "\1" >> Families6\/\2 \& /g' myfile.txt > run_jobs.sh # 让当前shell执行脚本(不要用sh run_jobs.sh!) source run_jobs.sh # 或者用短点写法 . run_jobs.sh
之后再敲jobs,就能看到那些后台作业的状态了。
方法2:用eval直接在当前shell解析执行
不想生成临时文件的话,可以把sed的输出用eval交给当前shell处理,跳过子shell:
eval "$(sed 's/\(.*\)\t\(.*\)/ echo "\1" >> Families6\/\2 \& /g' myfile.txt)"
这样sed生成的每一条后台命令都会直接在你当前的shell里启动,jobs自然能追踪到它们。
方法3:保存PID来追踪进程(适合非要用管道的场景)
如果一定要保留管道的执行方式,那可以修改sed的生成逻辑,让每个后台进程把自己的PID写入一个文件,之后通过PID来查看状态:
# 生成命令时,额外把后台进程的PID写入job_pids.txt sed 's/\(.*\)\t\(.*\)/ echo "\1" >> Families6\/\2 \& echo $! >> job_pids.txt /g' myfile.txt | sh # 查看这些进程的状态 ps -p $(cat job_pids.txt)
$!是shell里的特殊变量,代表最后一个后台进程的PID,这样你就能通过PID列表来追踪每个作业的运行情况了。
内容的提问来源于stack exchange,提问作者Ricardo Guerreiro
相关产品推荐
相关产品推荐

