扫描进程输出,如果找到字符串则终止

时间:2016-11-08 13:10:33

标签: bash macos shell

在bash中,如何启动并“监视”给定字符串的进程输出?

发现此字符串后,我想终止该过程。

E.g。

monitor myProgram ">>45Error;"

会启动myProgram并在输出">>45Error;"

后立即停止

2 个答案:

答案 0 :(得分:1)

除非myprogram处理/忽略损坏的管道信号(SIGPIPE),否则以下工作将完成:

myprogram|grep --max-count 1 ">>45Error;"

修改

以下是chepner's answer and comments therein之上构建的请求monitor脚本。

#!/usr/bin/env bash

set -m

tmpdir="$(mktemp -d)"
fifo="$tmpdir/fifo"
trap "rm -rf $tmpdir" EXIT

terminating_pattern=$1
shift

mkfifo "$fifo"

eval "$@" 2>&1|tee "$fifo" &

grep -q "$terminating_pattern" < "$fifo"
kill %%

请注意,输入命令行是使用eval执行的,这意味着执行了额外的扩展级别。如果不合适,请删除eval

测试:

$ ./monitor 49 'for i in {1..100}; do echo $((i*i)); sleep 1; done;'
1
4
9
16
25
36
49
./monitor: line 1:  9638 Terminated              eval "$@" 2>&1
      9639                       | tee "$fifo"

答案 1 :(得分:0)

@ Leon的改进版本的答案即使myprogram忽略SIGPIPE也有效:

mkfifo output
myprogram > output & pid=$!
grep --max-count 1 ">>45Error;" < output && kill $pid

但是,输出到交互设备以外的任何内容都将被缓冲,因此在myprogram写入字符串和grep实际读取的时间之间可能存在延迟(如@ hek2mgl指出的那样)字符串。有特定于操作系统的方法来限制与管道关联的缓冲区的大小,或者完全禁用它。