Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make grep exit early when it finds a match

Tags:

grep

bash

I have the following line in bash.

(sleep 1 ; echo "foo" ; sleep 1 ; echo "bar" ; sleep 30) | nc localhost 2222 \
| grep -m1 "baz"

This prints "baz" (if/when the other end of the TCP connection sends it) and exits after 32 seconds.

What I want it to do is to exit the sleep 30 early if it sees "baz". The -m flag exits grep, but does not kill the whole line.

How could I achieve this in bash (without using expect if possible)?


Update: the code above does quit, if and only if, the server tries to send something after baz. This does not solve this problem, as the server may not send anything for minutes.

like image 841
fadedbee Avatar asked Feb 11 '23 15:02

fadedbee


1 Answers

If you like esoteric sides of Bash, you can use coproc for that.

coproc { { sleep 1; echo "foo"; sleep 1; echo "bar"; sleep 30; } | nc localhost 2222; }
grep -m1 baz <&${COPROC[0]}
[[ $COPROC_PID ]] && kill $COPROC_PID

Here, we're using coproc to run

{ { sleep 1; echo "foo"; sleep 1; echo "bar"; sleep 30; } | nc localhost 2222; }

in the background. coproc takes care to redirect the standard output and standard input of this compound command in the file descriptors set in ${COPROC[0]} and ${COPROC[1]}. Moreover, the PID of this job is in COPROC_PID. We then feed grep with the standard output of the background job. It's then easy to kill the job when we're done.

like image 196
gniourf_gniourf Avatar answered Feb 20 '23 05:02

gniourf_gniourf