4

I want to play a sound after a command finishes, but only if the command took more than a second.

I have this code (copied from https://stackoverflow.com/a/11056286/1757964 and modified slightly):

( $COMMAND ) & PID=$!
( sleep 1; wait -f $PID 2>/dev/null; paplay "$SOUND" ) 2>/dev/null & WATCH=$!
wait -f $PID 2>/dev/null && pkill -HUP -P $WATCH

The "wait" on the second line seems to terminate immediately, though. I tried the -f flag but the behavior didn't change. How can I make the "wait" actually wait?

APerson
  • 8,140
  • 8
  • 35
  • 49

2 Answers2

3

The problem is that you're running wait in a subshell. A shell can only wait for its own children, but the process you're trying to wait for is a sibling of the subshell, not a child.

There's no need to use wait for this. The question you copied the code from is for killing a process if it takes more than N seconds, not for telling how long a command took.

You can use the SECONDS variable to tell if it took more than a second. This variable contains the number of seconds since the shell started, so just check if it has increased.

start=$SECONDS
$COMMAND
if (($SECONDS > $start))
then
    paplay "$SOUND"
fi
Barmar
  • 741,623
  • 53
  • 500
  • 612
2

I'd probably want to streamline this to capture the data (in # of seconds since epoch) and then compare the difference (and if > 1 second then play sound), eg:

prgstart=$(date '+%s')    # grab current time in terms of # of seconds since epoch

$COMMAND                  # run command in foreground => no need for sleep/wait/etc; once it completes ...

prgend=$(date '+$s')      # grab current time in terms of # of seconds since epoch

if [[ $(( ${prgend} - ${prgstart} )) -gt 1 ]]
then
    paplay "$SOUND"
fi
markp-fuso
  • 28,790
  • 4
  • 16
  • 36