21

I'm trying to create some error reporting using a Trap to call a function on all errors:

Trap "_func" ERR

Is it possible to get what line the ERR signal was sent from? The shell is bash.

If I do that, I can read and report what command was used and log/perform some actions.

Or maybe I'm going at this all wrong?

I tested with the following:

#!/bin/bash
trap "ECHO $LINENO" ERR

echo hello | grep "asdf"

And $LINENO is returning 2. Not working.

  • You can look at the bash debugger script bashdb. It seems that the first argument to trap can contain variables that are evaluated in the desired context. So trap 'echo $LINENO' ERR' should work. – donothingsuccessfully May 29 '12 at 18:53
  • hmm just tried this with a bad echo | grep command and it returns the line of the Trap statement. But I'll take a look at bashdb – Mechaflash May 29 '12 at 18:56
  • I'm so sorry... I didn't specify in my original question that I need a native solution. I edited the question. – Mechaflash May 29 '12 at 19:05
  • Sorry, I borked the example line: trap 'echo $LINENO' ERR. The first argument to trap is the entire echo $LINENO hardquoted. This is in bash. – donothingsuccessfully May 29 '12 at 19:43
  • 4
    @Mechaflash It would have to be trap 'echo $LINENO' ERR, with single quotes, not double quotes. With the command you wrote, $LINENO is expanded when line 2 is parsed, so the trap is echo 2 (or rather ECHO 2, which would output bash: ECHO: command not found). – Gilles May 29 '12 at 23:56
46

As pointed out in comments, your quoting is wrong. You need single quotes to prevent $LINENO from being expanded when the trap line is first parsed.

This works:

#! /bin/bash

err_report() {
    echo "Error on line $1"
}

trap 'err_report $LINENO' ERR

echo hello | grep foo  # This is line number 9

Running it:

 $ ./test.sh
 Error on line 9
  • thanks for the example with a function call. I didn't know that double quotes expanded the variable in this case. – Mechaflash May 30 '12 at 14:23
  • echo hello | grep foo doesn't seem to throw error for me. Am I misunderstanding something? – geotheory Dec 2 '15 at 22:15
  • @geotheory On my system grep has an exit status of 0 if there was a match, 1 if there was no match and >1 for an error. You can check the behavior on your system with echo hello | grep foo; echo $? – Patrick Dec 7 '15 at 23:17
  • No you're right it is an error :) – geotheory Dec 8 '15 at 9:56
  • Don't you need to use -e on the invocation line, to cause error on command failure? That is: #!/bin/bash -e ? – Tim Bird Mar 31 '17 at 22:39
10

You can also use the bash builtin 'caller':

#!/bin/bash

err_report() {
  echo "errexit on line $(caller)" >&2
}

trap err_report ERR

echo hello | grep foo

it prints filename too:

$ ./test.sh
errexit on line 9 ./test.sh

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.