首页 > 解决方案 > 如何从长时间运行的命令中获取单行输入,然后将其杀死?

问题描述

有没有办法从流中获取一行输入,将其作为参数传递并终止流?

在伪 bash 代码中:

tail -f stream | filter | take-one-and-kill-tail | xargs use-value

编辑:到目前为止的实际脚本是:

i3-msg -t subscribe -m '["window"]'| stdbuf -o0 -e0 jq -r 'select(.change == "new") | "\(.container.window)\n"' | head -0

它具有以下(不良)行为:

$ i3-msg -t subscribe -m '["window"]'| stdbuf -oL -eL jq -r 'select(.change == "new") | "\(.container.window)\n\n"' | head -1
# first event happens, window id is printed
79691787
# second event happens, head -1 quits
$

标签: bashshell

解决方案


您可以在子shell 中运行该命令并杀死该shell。

在此示例中,我在第一条信息消息之后终止了流:

#!/bin/bash

( sudo stdbuf -oL tail -f /var/log/syslog | stdbuf -oL grep -m1 info  ; kill $$ )

注意:( pipeline )将在子外壳中运行管道。$$包含当前 shell 的 pid。(即上面示例中的子shell)


在上面的示例grep -m1中,确保在终止管道之前只读取/写入一行输出。

如果您的过滤器程序不支持这样的选项-m1,您可以在输入的第一行之后通过管道连接到 awk 并退出 awk。其余概念保持不变:

( sudo stdbuf -oL tail -f /var/log/syslog \
  | stdbuf -oL grep info \
  | awk '{print;exit}' ; kill $$) 

推荐阅读