2

I have a program that continuously runs and is piped into grep and every once in a while grep finds a match. I want my bash script to execute when grep finds the match.

Like this:

program | grep "pattern"  

grep outputs -> script.sh executes

2
  • You'll want to save the grep results into a variable, then use bash's built in syntax for if to conditionally trigger another command Commented Dec 10, 2021 at 16:51
  • But grep never finishes executing, just keeps pumping out output when it found a match in program's output. How to save that to a variable? Commented Dec 10, 2021 at 16:57

3 Answers 3

5

If I understand your question correct (the "every once in a while grep finds a match" part), your program produces the positive pattern several times during its longish runtime and you want script.sh run at those points in time .

When you pipe program to grep and watch on greps exit code with &&, then you execute script.sh only once and only at the end of programs runtime.

If my assumptions are correct (that you want script.sh run several times), then you need "if then logic" behind the | symbol. One way to do it is using awk instead of grep:

program | awk '/pattern/ {system("./script.sh")}'
  • /pattern/ {system("./script.sh")} in single quotes is the awk script
    • /pattern/ instructs awk to look for lines matching pattern and do the instructions inside the following curly braces
    • system("./script.sh") inside the curly braces behind the /.../ executes the script.sh in current directory via awks system command

The overall effect is: script.sh is executed as often as there are lines matching pattern in the output of program.

Another way to this is using sed:

program | sed -n '/pattern/ e ./script.sh'
  • -n prevents sed from printing every line in programs out put
  • /pattern/ is the filter criteria for lines in programs output: lines must match pattern
  • e ./script.sh is the action that sed does when a line matches the pattern: it executes your script.sh
Sign up to request clarification or add additional context in comments.

Comments

4

Use -q grep parameter and && syntax, like this:

program | grep -q "pattern" && sh script.sh

where:

-q: Runs in quiet mode but exit immediately with zero status if any match is found

&&: is used to chain commands together, such that the next command is run if and only if the preceding command exited without errors (or, more accurately, exits with a return code of 0). Explained here.

sh script.sh: Will run only if "pattern" is found

2 Comments

I understand the original question asks about continuous monitoring the output of program, so a single execution of grep and script.sh is not enough. Lars Fischer answer bellow addresses the continuous execution.
@ASB, you right, I didn't catch that, thanks for clarifying.
1

Equivalent to @masterguru's answer, but perhaps more understandable:

if program | grep -q "pattern"
then
    # execute command here
fi

grep returns a zero exit status when it finds a match, so it can be used as a conditional in if.

Comments

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.