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

重写Shell脚本以避免cat绕过XDG_RUNTIME_DIR存在性检查

解决FIFO驱动进程在目录消失后无法终止的问题

问题原因

你原脚本的逻辑存在缺陷:while [ -e "${XDG_RUNTIME_DIR}" ]; do cat ${FIFO} ; done中,cat ${FIFO}会持续阻塞等待FIFO输入,只有当FIFO被关闭或数据读取完成后,才会回到while循环的条件检查步骤。如果XDG_RUNTIME_DIR在cat阻塞期间被删除,循环根本没机会执行存在性检查,导致cat和下游的my_program一直挂起运行。

修复方案

方法一:后台监控目录状态,触发进程组终止

这是最可靠的方式,通过后台进程定期检查目录是否存在,一旦目录消失就终止整个进程组的所有相关进程:

#!/bin/sh

# 启动后台监控进程,定期检查目录状态
(
    while [ -e "${XDG_RUNTIME_DIR}" ]; do
        sleep 1  # 可根据需求调整检查间隔,比如改为sleep 0.5
    done
    kill 0  # 终止当前进程组内的所有进程(包括监控进程、cat、my_program)
) &

# 持续读取FIFO并传递给my_program
cat "${FIFO}" | my_program

方法二:循环读取FIFO,每次读取前检查目录

如果不想依赖后台进程,可以改用逐行读取FIFO的方式,确保循环能定期回到目录存在性检查:

#!/bin/sh

# 打开FIFO文件描述符
exec 3<>"${FIFO}"

while [ -e "${XDG_RUNTIME_DIR}" ]; do
    # 读取FIFO的一行内容,读取失败则退出循环
    if ! read -r line <&3; then
        break
    fi
    # 将内容传递给my_program
    echo "$line"
done

# 关闭文件描述符
exec 3>&- | my_program

补充说明

  • 方法一中的kill 0会向当前进程组的所有进程发送终止信号,确保所有相关进程(监控脚本、cat、my_program)都能被彻底清理。
  • 方法二中的逐行读取会在每次读取后回到while条件检查,但如果FIFO长时间无数据,read会阻塞,此时仍无法检测目录变化——这种场景下方法一更优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:10:13