SyntaxT3rr0r
SyntaxT3rr0r

Reputation: 28293

Bash: how to interrupt this script when there's a CTRL-C?

I wrote a tiny Bash script to find all the Mercurial changesets (starting from the tip) that contains the string passed in argument:

#!/bin/bash

CNT=$(hg tip | awk '{ print $2 }' | head -c 3)
while [ $CNT -gt 0 ]
do
    echo rev $CNT
    hg log -v -r$CNT | grep $1       
    let CNT=CNT-1
done

If I interrupt it by hitting ctrl-c, more often than not the command currently executed is "hg log" and it's that command that gets interrupted, but then my script continues.

I was then thinking of checking the return status of "hg log", but because I'm piping it into grep I'm not too sure as to how to go about it...

How should I go about exiting this script when it is interrupted? (btw I don't know if that script is good at all for what I want to do but it does the job and anyway I'm interested in the "interrupted" issue)

Upvotes: 7

Views: 6403

Answers (3)

Arkku
Arkku

Reputation: 42139

Place at the beginning of your script: trap 'echo interrupted; exit' INT

Edit: As noted in comments below, probably doesn't work for the OP's program due to the pipe. The $PIPESTATUS solution works, but it might be simpler to set the script to exit if any program in the pipe exits with an error status: set -e -o pipefail

Upvotes: 6

Dan Story
Dan Story

Reputation: 10155

Rewrite your script like this, using the $PIPESTATUS array to check for a failure:

#!/bin/bash

CNT=$(hg tip | awk '{ print $2 }' | head -c 3)
while [ $CNT -gt 0 ]
do
    echo rev $CNT
    hg log -v -r$CNT | grep $1
    if [ 0 -ne ${PIPESTATUS[0]} ] ; then
            echo hg failed
            exit
    fi     
    let CNT=CNT-1
done

Upvotes: 5

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798744

The $PIPESTATUS variable will allow you to check the results of every member of the pipe.

Upvotes: 1

Related Questions