4

I have searched for this and expected to find hundreds of solutions yet found none !

I would like to read the STDOUT stream and wait for a specific string to appear, without waiting for the process to finish.

What I have now, waits for the process to finish before returning the output:

RESP=$(execute some command 2>&1)
if $RESP contains something then do something;

How can I read the stream in real-time rather than waiting for it to complete ?

EDIT

I tried the following suggested by paddy which for testing works with the ping command:

RESP=$(ping 192.168.0.1 | grep seq=5 -m1)

However it does not work with the command I want to use dhcpcd:

RESP=$(dhcpcd wlan0 -r 192.168.0.190 | grep claims -m1)

Unlike the ping test, the output from the command is sent to the console instead of being hidden, and it never detects the "claims" text even though it is present in the output ?

crankshaft
  • 2,607
  • 4
  • 45
  • 77
  • 1
    Are you sure the output of dhcpcd goes to stdout? Might it come through stderr to your console? In this case you should redirect `2>&1` stderr-output to the stdout-output. – urzeit Nov 22 '13 at 08:46
  • See https://unix.stackexchange.com/questions/117501/in-bash-script-how-to-capture-stdout-line-by-line – Cees Timmerman May 09 '19 at 08:20

2 Answers2

3

You can pipe into grep to do the matching and have it exit when it encounters a match. That will also exit the program producing the output.

if mycommand | grep something -q; then
    dosomething
fi

The above will quit if anything matches (-q), but not display the result. If you want to see the output, you can quit on the first match (using -m1):

RESP=$(mycommand | grep something -m1)

Read the man-pages for grep for more information.


If you don't want to cancel the program producing the output, you could try writing it to file in the background, then tail that file:

mycommand > output &
if tail -f output | grep something -q; then
    dosomething
fi
paddy
  • 60,864
  • 6
  • 61
  • 103
  • Hmmm, actually, forget that last suggestion - it's too naive: If the text is not found it will wait indefinitely. Hopefully the first or second solutions are what you're looking for. – paddy Nov 22 '13 at 01:22
  • Hmm, I tested this with a ping and it worked, but I tested with the dhcpcd command and it does not. I have added to original question. – crankshaft Nov 22 '13 at 08:34
0

From this unix.stackexchange answer I got following solution:

cmd_which_streams_new_lines \
| while read -r line; do
  # process your line here
  echo "${line}"

  # when you're done, break the loop (be prepared for messy stderr)
done
porkbrain
  • 720
  • 5
  • 16