如何在Bash脚本中用$!获取目标pio进程PID并避免误杀?
用$!精准获取PID避免误杀进程的Bash脚本实现
问题背景
原本通过ps -ef | awk '/pio/{print $2}'获取pio device monitor进程PID的方式,会误匹配脚本中其他同类pio命令,存在误杀风险。需要改用$!来精准定位目标进程的PID,同时实现后台运行命令、提取12位字符结果后终止进程的需求。
实现方案
方法一:子shell后台运行+临时文件捕获输出
将整个管道命令放入子shell后台执行,用$!获取子shell的PID,通过临时文件保存提取结果,最后清理文件并终止相关进程:
# 创建临时文件存储提取结果 temp_output=$(mktemp) # 将管道命令放入子shell后台运行,捕获子shell PID (pio device monitor -p COM22 -b 115200 --no-reconnect | grep -E -o -m 1 '[A-Za-z0-9]{12}' > "$temp_output") & subshell_pid=$! # 等待grep找到结果后退出 wait $subshell_pid # 读取提取到的目标字符 IDFound=$(cat "$temp_output") # 清理临时文件 rm -f "$temp_output" # 终止可能残留的pio子进程 pkill -P $subshell_pid pio # 输出结果 echo "提取到的目标字符:$IDFound"
方法二:使用coproc协程(更简洁)
利用Bash协程直接捕获pio进程的PID,无需临时文件,流程更高效:
# 启动协程运行pio monitor,协程PID自动存入MONITOR_PID coproc MONITOR { pio device monitor -p COM22 -b 115200 --no-reconnect; } # 从协程输出中提取目标字符,grep找到结果后立即退出 IDFound=$(grep -E -o -m 1 '[A-Za-z0-9]{12}' <&${MONITOR[0]}) # 终止pio进程 kill ${MONITOR_PID} # 输出结果 echo "提取到的目标字符:$IDFound"
关键说明
$!仅能获取最后一个后台进程的PID,因此需将整个管道放入子shell或协程后台执行,避免只拿到grep的PID。- 协程方式无需临时文件,
MONITOR_PID直接对应pio device monitor进程,精准度更高。 grep -m 1参数确保找到第一个匹配结果后立即退出,减少资源占用。
内容的提问来源于stack exchange,提问作者jetLagMan
相关产品推荐
相关产品推荐

