Skip to main content
3 of 8
added 315 characters in body
markp-fuso
  • 1.7k
  • 1
  • 9
  • 11

From OP's comments it sounds like all mycommand output is going to stderr ... maybe. OP has also clarified that mycommand is writing directly to the log file.

I'm going to assume we don't know, for sure, if output is going to stdout, stderr or a mix.

For demo purposes I'll use the following:

% cat mycommand
#!/bin/zsh

for str in "starting ..." "running ..." "ERROR: had a problem" "stopping"
do
    if [[ "${str}" =~ ERROR: ]]
    then
        echo "${str}" >&2               # remove ">&2" to write to stdout
    else
        echo "${str}"                   # append ">&2" to write to stderr
    fi
    sleep 2
done

One approach using redirection to split the output (to monitor and follow-on processing) and grep to find lines we wish to feed to espeak:

% ./mycommand 1> >(tee /dev/tty | grep --line-buffered '^ERROR:' | espeak) 2>&1
starting ...
running ...
ERROR: had a problem               # espeak output heard on speakers
stopping

NOTES:

  • regardless of modifying mycommand to send output to stdout, stderr or a mix of stdout/stderr ...
  • in my system I hear ERROR <pause> had a problem over my speakers as the line ERROR: had a problem was printed to the terminal
  • tee /dev/tty - insures all data coming in on stdout is copied to the terminal before being piped to grep
  • 2>&1 - insures all data coming in on stderr is redirected to stdout (which means stderr is also routed through the tee /dev/tty | grep ... | espeak pipeline)
  • grep is used to extract just the lines we wish to pass to espeak; if looking for multiple strings you'll likely need to enable extended regex support (eg, grep -E ...)
  • --line-buffered is a GNU grep extension that insures we hear the espeak output at the same time as we see the ERROR: line
  • OP can install espeak via sudo apt install espeak
  • OP can replace espeak with whatever sound producing program they wish
markp-fuso
  • 1.7k
  • 1
  • 9
  • 11