我正在寻找一种以编程方式监视命令输出直到观察到特定字符串然后退出的方法。这与这个问题非常相似,但我不想尾随文件,而是想“尾随”命令。
就像是:
看-n1 my_cmd | grep -m 1“字符串我正在寻找”
(但这对我不起作用。)
更新:我需要弄清楚'my_cmd'不会连续输出文本,而是需要重复调用直到找到字符串为止(这就是为什么我想到'watch'命令的原因)。在这方面,“ my_cmd”就像许多其他Unix命令一样,例如:ps,ls,lsof,last等。
我正在寻找一种以编程方式监视命令输出直到观察到特定字符串然后退出的方法。这与这个问题非常相似,但我不想尾随文件,而是想“尾随”命令。
就像是:
看-n1 my_cmd | grep -m 1“字符串我正在寻找”
(但这对我不起作用。)
更新:我需要弄清楚'my_cmd'不会连续输出文本,而是需要重复调用直到找到字符串为止(这就是为什么我想到'watch'命令的原因)。在这方面,“ my_cmd”就像许多其他Unix命令一样,例如:ps,ls,lsof,last等。
Answers:
使用循环:
until my_cmd | grep -m 1 "String Im Looking For"; do : ; done
代替:
,您可以使用sleep 1
(或0.2)简化CPU。
循环运行直到grep在命令的输出中找到字符串为止。-m 1
表示“一个匹配就足够了”,即grep找到第一个匹配项后便停止搜索。
您还可以使用grep -q
which在找到第一个匹配项后退出,但不打印匹配行。
grep -q
这是另一种选择。找到字符串后,grep退出。
watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
!
否定命令管道的退出代码grep -m 1
找到字符串时退出watch -e
如果发生任何错误,则返回但这可以进行改进,以实际显示匹配的行,到目前为止已将其丢弃。
watch
命令(CentOS)没有-e
标志(这应该没关系)。不过,更重要的是,当找到字符串时,监视将继续运行并且不会退出。看来,当grep -m
退出时,它只会退出kills my_cmd
,而不会退出watch
。
tee
为,但这导致一个误导换行,我不知道该怎么现在规避:watch -n1 -e "! date | tee /dev/tty | grep --color -m 1 \"17\""
watch
找到该字符串时,它会忠实地停止观看,但是直到您按下某个键时,它才真正退出。很近。
对于那些具有不断向stdout写入程序的程序,您只需使用'single match'选项将其通过管道传送到grep。grep找到匹配的字符串后,它将退出,这将关闭通过管道传递给grep的进程的stdout。只要进程再次写入,此事件自然就应该导致程序正常退出。
将会发生的是,当grep退出后,该进程尝试写入已关闭的stdout时,该进程将收到SIGPIPE。这是ping的示例,否则将无限期运行:
$ ping superuser.com | grep -m 1 "icmp_seq"
此命令将与第一个成功的“ pong”匹配,然后在下次ping
尝试写入stdout 时退出。
然而,
并不总是保证该进程将再次写入stdout,因此可能不会导致SIGPIPE升高(例如,在尾随日志文件时可能会发生这种情况)。在这种情况下,我设法提出的最佳解决方案是写入文件。如果您认为可以改善,请发表评论:
$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }
分解如下:
tail -f log_file & echo $! > pid
-尾部文件,将进程附加到后台,并将PID($!
)保存到文件。我尝试将PID导出为变量,但是在这里和再次使用PID时似乎存在竞争条件。{ ... ;}
- 组在一起使用这些指令,所以我们可以通过管道输出,同时保持当前上下文(保存和重新使用变量时会有所帮助,但无法得到的那部分工作)的grep|
-将左侧的stdout管道到右侧的stdingrep -m1 "find_me"
-查找目标字符串&& kill -9 $(cat pid)
- 一旦找到匹配的字符串,在退出后强制杀死(SIGKILL)tail
进程 grep
&& rm pid
-删除我们创建的文件my_cmd | tail +1f | sed '/String Im Looking For/q'
如果tail
不支持+1f
语法,请尝试tail -f -n +1
。(-n +1
告诉它从开头开始;tail -f
默认情况下从输出的最后10行开始。)
tail -f
像文件一样输出程序输出...我错了吗?