3

Is it possible to somehow run an executable through the shell and automatically make it stop executing the moment a specific string is matched/detected in the output? Just as if i would hit CTRL+C, manually?

If yes, how?

2 Answers 2

4

use a coprocess:

coproc CO { yourcommand; }
while read -ru ${CO[0]} line
do
    case "$line" in
        *somestring*) kill $CO_PID; break ;;
    esac
done

Note that if the command buffers its output, as many commands do when writing to a pipe, there will be some delay before the string is detected.

Sign up to request clarification or add additional context in comments.

2 Comments

I don't find any coproc binary on my system. I'm on Mac OSX, should have included that in my question though.
It's not a binary, it's built into bash 4.x. Unfortunately, OS X has bash 3.x. If you google bash coprocesses, you can find out how to do the same thing using named pipes.
3

You could use awk:

program | awk '/pattern/{exit}1'

If you also want to print the line containing the pattern, say:

program | awk '/pattern/{print;exit}1'

For example:

$ seq 200 | awk '/9/{print;exit}1'
1
2
3
4
5
6
7
8
9

EDIT: (With reference to your comment, whether the program would stop or not.) Following is a script that would execute in an infinite loop:

n=1
while : ; do
  echo $n
  n=$((n+1))
  sleep 1
done

This script foo.sh was executed by saying:

$ time bash foo.sh | awk '/9/{print;exit}1'
1
2
3
4
5
6
7
8
9

real    0m9.097s
user    0m0.011s
sys     0m0.011s

As you can see, the script terminated when the pattern was detected in the output.


EDIT: It seems that your program buffers the output. You could use stdbuf:

stdbuf -o0 yourprogram | awk '/pattern/{print;exit}1'

If you're using mawk, then say:

stdbuf -o0 yourprogram | mawk -W interactive '/pattern/{print;exit}1'

7 Comments

It seems that using this, the program is still having to finish. It takes as long as if i call it without awk. Is this possible?
@SquareCat No, the program should finish. awk would send a SIGPIPE to the program which should terminate it. See the edit above for a demo.
If the program produces output slowly, it could run for a while before the SIGPIPE is generated, though.
@tripleee Good thought, I'll suggest using stdbuf.
@SquareCat It seems that the output is buffered; the edit above might work for you.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.