Trap, ERR, and echoing the error line
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
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
I really like the answer given by @Mat above. Building on this, I wrote a little helper which gives a bit more context for the error:
We can inspect the script for the line which caused the failure:
err() {
echo "Error occurred:"
awk 'NR>L-4 && NR<L+4 { printf "%-5d%3s%s\n",NR,(NR==L?">>>":""),$0 }' L=$1 $0
}
trap 'err $LINENO' ERR
Here it is in a small test script:
#!/bin/bash
set -e
err() {
echo "Error occurred:"
awk 'NR>L-4 && NR<L+4 { printf "%-5d%3s%s\n",NR,(NR==L?">>>":""),$0 }' L=$1 $0
}
trap 'err $LINENO' ERR
echo one
echo two
echo three
echo four
false
echo five
echo six
echo seven
echo eight
When we run it we get:
$ /tmp/test.sh
one
two
three
four
Error occurred:
12 echo two
13 echo three
14 echo four
15 >>>false
16 echo five
17 echo six
18 echo seven