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

如何从长期运行的命令输出流中取单行输入后终止该命令?

流读取一行后立刻终止上游进程的解决方案

根因分析

你遇到的延迟退出问题是Linux管道的默认机制导致的:下游进程(如head -1)退出后,上游进程只有在尝试向已经关闭的管道写入数据时,才会收到SIGPIPE信号触发退出。你脚本里的i3-msg属于事件监听类进程,在输出第一行后会阻塞等待下一个窗口事件,直到第二个事件触发、尝试写管道时才会感知到下游已退出,因此出现了需要等第二次事件才结束的表现。

可用方案

方案1:原生Bash实现(无额外依赖,最可靠)

通过后台运行管道+进程组控制的方式,读取到第一行后主动杀死所有上游进程,无需等待下一次事件触发:

#!/bin/bash
set -m
# 后台运行监听管道,记录进程组ID
i3-msg -t subscribe -m '["window"]' | stdbuf -o0 jq -r 'select(.change == "new") | .container.window' &
PGID=$!
# 读取第一行输出
read -r WIN_ID < <(tail -f --pid="$PGID" /proc/$PGID/fd/1)
# 读到后立刻终止整个上游进程组
kill -TERM -"$PGID"
# 你后续的业务逻辑,比如传给目标命令使用
echo "$WIN_ID" | xargs your-command

方案2:极简单行写法(适合快速使用)

用进程替换配合kill逻辑实现单行执行:

read -r WIN_ID < <(i3-msg -t subscribe -m '["window"]' | stdbuf -o0 jq -r 'select(.change == "new") | .container.window'; kill $PPID) && echo "$WIN_ID" | xargs your-command

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:09:02