我正在寻找一种以编程方式观察命令输出的方法,直到观察到特定字符串然后退出。这与this question非常相似,但我不想拖尾文件,而是要“拖尾”命令。
就像是:
看 -n1 my_cmd | grep -m 1 "我正在寻找的字符串"
(但这对我不起作用。)
更新:我需要澄清“my_cmd”不会连续输出文本,而是需要重复调用直到找到字符串(这就是我想到“watch”命令的原因)。在这方面,“my_cmd”就像许多其他 unix 命令,例如:ps、ls、lsof、last 等。
cho*_*oba 47
使用循环:
until my_cmd | grep -m 1 "String Im Looking For"; do : ; done
Run Code Online (Sandbox Code Playgroud)
代替:,您可以使用sleep 1(或 0.2)来减轻 CPU 负担。
循环一直运行,直到 grep 在命令的输出中找到字符串。-m 1意思是“一个匹配就足够了”,即 grep 在找到第一个匹配后停止搜索。
您还可以使用grep -qwhich 在找到第一个匹配项后也退出,但不打印匹配行。
mat*_*ath 13
watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
Run Code Online (Sandbox Code Playgroud)
! 否定命令管道的退出代码grep -m 1 找到字符串时退出watch -e 如果发生任何错误,则返回但这可以改进以实际显示匹配的行,该行目前已被丢弃。
Bla*_*lia 10
对于那些拥有连续写入标准输出的程序的人,您需要做的就是使用“单一匹配”选项将其通过管道传送到 grep。一旦 grep 找到匹配的字符串,它将退出,这将关闭正在通过管道传输到 grep 的进程的标准输出。这个事件应该自然地导致程序正常退出,只要过程中再次写道。
将会发生的情况是,该进程在 grep 退出后尝试写入已关闭的标准输出时将收到一个 SIGPIPE。这是一个带有 ping 的示例,否则它将无限期运行:
$ ping superuser.com | grep -m 1 "icmp_seq"
Run Code Online (Sandbox Code Playgroud)
此命令将匹配第一个成功的“pong”,然后在下次ping尝试写入 stdout时退出。
然而,
并不总是保证进程会再次写入标准输出,因此可能不会引发 SIGPIPE(例如,拖尾日志文件时可能会发生这种情况)。我设法针对这种情况提出的最佳解决方案涉及写入文件;如果您认为可以改进,请发表评论:
$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }
Run Code Online (Sandbox Code Playgroud)
打破这个:
tail -f log_file & echo $! > pid- 拖尾文件,将进程附加到后台,并将 PID ( $!)保存到文件。我尝试将 PID 导出到变量,但似乎在这里和再次使用 PID 之间存在竞争条件。{ ... ;}-组在一起使用这些指令,所以我们可以通过管道输出,同时保持当前上下文(保存和重新使用变量时会有所帮助,但无法得到的那部分工作)的grep| - 管道左侧的标准输出到右侧的标准输入grep -m1 "find_me" - 找到目标字符串&& kill -9 $(cat pid)-一旦找到匹配的字符串,就在退出后强制终止(SIGKILL)tail进程 grep&& rm pid - 删除我们创建的文件