MST
星途 面试题库

面试题:Bash后台作业与前台作业切换及状态管理

在Bash脚本中,启动了多个后台作业,比如 `command1 &`、`command2 &` 等。如何在脚本中实时获取这些后台作业的运行状态,并在其中一个作业完成后,将另一个指定的后台作业切换到前台继续执行?
35.6万 热度难度
编程语言Bash

知识考点

AI 面试

面试题答案

一键面试
  1. 获取后台作业运行状态
    • 在Bash脚本中,可以使用 jobs 命令来获取当前Shell会话中所有后台作业的状态。例如:
    jobs -l
    
    这个命令会列出所有后台作业,每行的格式类似 [job_number] [status] [command],其中 job_number 是作业编号,status 表示作业状态(如 RunningStopped 等),command 是作业执行的命令。
  2. 在一个作业完成后将另一个指定作业切换到前台
    • 可以使用 wait 命令结合作业编号来等待特定作业完成。然后使用 fg 命令将指定作业切换到前台。假设启动了两个后台作业:
    command1 &
    job1_pid=$!
    command2 &
    job2_pid=$!
    wait $job1_pid
    fg %$(jobs -p | grep -n $job2_pid | cut -d: -f1)
    
    • 解释:
      • command1 &command2 & 分别启动两个后台作业,并通过 $! 获取它们的进程ID(PID),分别存储在 job1_pidjob2_pid 变量中。
      • wait $job1_pid 等待 command1 作业完成。
      • jobs -p 输出所有后台作业的PID,grep -n $job2_pid 查找 job2_pidjobs -p 输出中的行号,cut -d: -f1 提取行号,fg %行号 将指定行号对应的作业切换到前台。

另一种使用 trap 来捕获作业完成信号的方法:

command1 &
job1_pid=$!
command2 &
job2_pid=$!

finish_job() {
    if [ $1 -eq $job1_pid ]; then
        fg %$(jobs -p | grep -n $job2_pid | cut -d: -f1)
    fi
}
trap 'finish_job $!' SIGCHLD
  • 解释:
    • 定义了一个 finish_job 函数,当捕获到 SIGCHLD 信号(子进程状态改变,通常意味着有作业完成)时,会检查完成的作业是否是 command1(通过比较PID),如果是,则将 command2 作业切换到前台。
    • trap 'finish_job $!' SIGCHLD 设置了 SIGCHLD 信号的处理函数为 finish_job,并将完成作业的PID作为参数传递给 finish_job 函数。