Reputation: 1387
I have been looking for a way to print the line number inside the shell script when it errors out.
I came across '-x' option, which prints the line when running the shell script, but this is not exactly what I want. Maybe I could do $LINENO before every exit code? Is there a cleaner way to do it?
I just wanted the line number so I could open the shell script and directly go to the place where the interpreter realized the error.
Upvotes: 12
Views: 5136
Reputation: 295281
Using
PS4=':$LINENO+'
will add line number to the output of set -x
.
If you only want to print that on errors, there's some risk of running into bugs in recent interpreters. However, you can try the following (first given in this previous answer):
error() {
local parent_lineno="$1"
local message="$2"
local code="${3:-1}"
if [[ -n "$message" ]] ; then
echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}"
else
echo "Error on or near line ${parent_lineno}; exiting with status ${code}"
fi
exit "${code}"
}
trap 'error ${LINENO}' ERR
Again, this will not work on some recent builds of bash, which don't always have LINENO
set correctly inside traps.
Another approach (which will only work on recent shells; the below uses some bash 4.0 and 4.1 features) is to use PS4
to emit the exit status and line number of each command to a dedicated file descriptor, and use tail
to print only the last line given to that FD before the shell exits:
exec {BASH_XTRACEFD}> >(tail -n 1) # send set -x output to tail -n 1
PS4=':At line $LINENO; prior command exit status $?+'
set -x
Upvotes: 14