Bash中如何匹配stdout指定行后自动给目标进程发送SIGINT信号
可行实现方案
方案1:全兼容shell实现(无额外依赖)
先在脚本头部开启pipefail选项,保证进程退出码可以正确传递,再通过后台启动+逐行读取输出的逻辑实现需求:
#!/bin/bash set -euo pipefail # 自定义警告匹配关键词 MATCH_WORD="warning" # 后台启动foo_command,将标准输出重定向到文件描述符3,记录进程PID # 如需同时捕获stderr的警告,可在foo_command后添加 2>&1 exec 3< <(foo_command) FOO_PID=$! # 逐行读取foo_command的输出 while IFS= read -r line; do # 透传所有输出到标准输出 echo "$line" # 匹配到警告关键词 if [[ "$line" == *"$MATCH_WORD"* ]]; then # 发送SIGINT模拟手动中断 kill -SIGINT "$FOO_PID" 2>/dev/null || true # 等待进程退出后返回错误码 wait "$FOO_PID" 2>/dev/null || true exit 1 fi done <&3 # 进程正常运行结束,返回foo_command的原始退出码 wait "$FOO_PID" exit $?
方案优势
- 完全透传所有标准输出,无内容丢失
- 不会触发
foo_command的SIGPIPE异常,适配无法处理SIGPIPE的进程 - 完全保留
foo_command的原始退出码,运行报错场景会原封不动抛出错误 - 无需额外依赖,兼容所有标准bash环境
方案2:轻量单行版本(依赖GNU awk)
如果你的环境预装了GNU awk,也可以用更简洁的管道写法,注意该写法依赖bash 4.3+的进程PID获取规则,优先推荐使用方案1:
set -o pipefail foo_command | awk -v match_str="warning" '{ print $0; if ($0 ~ match_str) { system("kill -SIGINT " PPID); exit 1 } }'
内容的提问来源于stack exchange,提问作者Kache
相关产品推荐
相关产品推荐

