在bash中,如何启动并“监视”给定字符串的进程输出?
发现此字符串后,我想终止该过程。
E.g。
monitor myProgram ">>45Error;"
会启动myProgram
并在输出">>45Error;"
答案 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指出的那样)字符串。有特定于操作系统的方法来限制与管道关联的缓冲区的大小,或者完全禁用它。