“观察”命令的输出,直到观察到特定的字符串,然后退出

“观察”命令的输出,直到观察到特定的字符串,然后退出

我正在寻找一种方法来以编程方式观察命令的输出,直到观察到特定的字符串然后退出。这与问题,但我不想拖尾文件,而是想“拖尾”命令。

就像是:

watch -n1 my_cmd | grep -m 1 "String Im Looking For"

(但这对我不起作用。)

更新:我需要澄清的是,它不会my_cmd连续输出文本,而是需要反复调用,直到找到字符串(这就是我想到该watch命令的原因)。在这方面,它与许多其他 Unix 命令类似,my_cmd例如:ps、、、、等。lslsoflast

答案1

使用循环:

until my_cmd | grep -m 1 "String Im Looking For"; do : ; done

:您可以使用(或 0.2)来代替,sleep 1以减轻 CPU 负担。

循环运行,直到 grep 在命令的输出中找到该字符串。-m 1表示“一次匹配就足够了”,即 grep 在找到第一个匹配后停止搜索。

您还可以使用grep -q它在找到第一个匹配项后退出,但不打印匹配的行。

答案2

watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
  • !否定命令管道的退出代码
  • grep -m 1找到字符串后退出
  • watch -e如果发生任何错误则返回

但这可以得到改进,以实际显示迄今为止被丢弃的匹配行。

答案3

对于那些拥有不断向 stdout 写入的程序的人来说,您需要做的就是使用“单一匹配”选项将其通过管道传输到 grep。一旦 grep 找到匹配的字符串,它就会退出,从而关闭通过管道传输到 grep 的进程上的 stdout。此事件应该自然导致程序正常退出只要进程再次写入

实际情况是,在 grep 退出后,当进程尝试写入已关闭的标准输出时,它将收到 SIGPIPE。下面是 ping 的示例,否则它将无限期运行:

$ ping superuser.com | grep -m 1 "icmp_seq"

此命令将匹配第一个成功的“pong”,然后在下次ping尝试写入标准输出时退出。


然而,

进程不一定能再次写入 stdout,因此可能不会引发 SIGPIPE(例如,在跟踪日志文件时可能会发生这种情况)。针对这种情况,我设法想出的最佳解决方案是写入文件;如果您认为可以改进,请发表评论:

$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }

具体来说:

  1. tail -f log_file & echo $! > pid- 跟踪文件,将进程附加到后台,并将 PID ( $!) 保存到文件中。我尝试将 PID 导出到变量,但似乎此处与再次使用 PID 之间存在竞争条件。
  2. { ... ;}-团体这些命令组合在一起,这样我们就可以在保持当前上下文的同时将输出传送到 grep (有助于保存和重用变量,但无法使该部分正常工作)
  3. |- 将左侧的标准输出通过管道传输到右侧的标准输入
  4. grep -m1 "find_me"- 找到目标字符串
  5. && kill -9 $(cat pid)- 强制终止(SIGKILL)该tail进程 grep一旦找到匹配的字符串就退出
  6. && rm pid- 删除我们创建的文件

答案4

my_cmd | tail +1f | sed '/String Im Looking For/q'

如果tail不支持该+1f语法,请尝试tail -f -n +1。 (-n +1告诉它从头开始;tail -f默认情况下从最后 10 行输出开始。)

相关内容