You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

终止后台进程后Bash脚本ps命令末尾报错的原因

问题描述

编写Bash课程作业脚本时出现异常:脚本整体执行流程正常,但在第42行的ps命令输出完成后,会额外弹出错误提示:script.sh: line 42: <PID> Terminated sleep 900 &。预期是ps命令输出干净,kill命令有对应输出,或者错误提示出现在kill命令执行的行,而非ps之后。

相关脚本如下:

#!/bin/bash

# Clears screen and displays current running processes
clear
ps

# Pauses for 10 seconds
sleep 10

# Displays Parent Process ID using $BASHPID env var (expands to subshells)
# $BASHPID requires Bash 4 or later
echo
echo -e "Parent Process ID:	$BASHPID"
echo

# Creates background process: Pause for 900 seconds
sleep 900 &

# Displays background jobs
jobs -l

# Pauses for 10 seconds
sleep 10

# Uses jobs -l, grep (in case other jobs are running), and cut to find PID of background job and saves it as a variable
bgjob=$(jobs -l | grep "sleep 900" | cut -d" " -f2)

# Terminates the background job created
kill -SIGTERM $bgjob
# Displays current processes so you can verify background job sucsessfully terminated
echo
ps
echo

# Pauses for 10 seconds
sleep 10

exit 0
解决思路与方案
  • 这个延迟出现的提示是Bash的作业通知机制导致的:当后台进程被kill终止后,Bash不会立刻输出终止通知,而是会等到下一个前台命令执行完成后才打印这条信息,所以它会出现在ps命令输出之后。
  • 针对需求,可采用以下几种解决方法:
    1. 立即处理终止状态:在kill命令后添加wait $bgjob 2>/dev/null,手动触发Bash处理后台进程的终止状态,这样通知会在kill后立刻输出,不会延迟到ps之后。修改后的代码片段:
      kill -SIGTERM $bgjob
      wait $bgjob 2>/dev/null  # 处理后台进程终止状态,消除延迟提示
      echo
      ps
      echo
      
    2. 关闭作业通知:在脚本开头添加set +m关闭监控模式,这样Bash会完全禁止后台作业的终止通知输出。但注意这会影响脚本中所有后台作业的状态提示。
    3. 优化PID获取方式:原脚本通过jobs -l | grep | cut提取PID的方式不够可靠,建议直接在创建后台进程时保存PID:
      # 创建后台进程时直接捕获PID
      sleep 900 &
      bgjob=$!  # $! 指向最后一个启动的后台进程PID
      
      这种方式避免了因jobs输出格式变化导致的PID提取错误,稳定性更高。

内容的提问来源于stack exchange,提问作者Aaron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 23:47:29