user2441441
user2441441

Reputation: 1387

Shell script print line number when it errors out

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

Answers (1)

Charles Duffy
Charles Duffy

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

Related Questions