Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 582
user2441441 Avatar asked Mar 16 '15 16:03

user2441441


People also ask

How do I show line numbers in bash?

In Bash, $LINENO contains the line number where the script currently executing. If you need to know the line number where the function was called, try $BASH_LINENO . Note that this variable is an array.

What is ${} in shell script?

${} Parameter Substitution/Expansion A parameter, in Bash, is an entity that is used to store values. A parameter can be referenced by a number, a name, or by a special symbol.

How do I print line numbers using sed?

If you use = in sed the line number will be printed on a separate line and is not available in the pattern space for manipulation. However, you can pipe the output into another instance of sed to merge the line number and the line it applies to. Show activity on this post. = is used to print the line number.

How to find the line number where a script is running?

In Bash, $LINENO contains the line number where the script currently executing. If you need to know the line number where the function was called, try $BASH_LINENO. Note that this variable is an array. #!/bin/bash function log () { echo "LINENO: $ {LINENO}" echo "BASH_LINENO: $ {BASH_LINENO [*]}" } function foo () { log "$@" } foo "$@"

How to emit lineno in bash script?

You can change PS4 to emit the LINENO (The line number in the script or shell function currently executing). $ PS4='Line $ {LINENO}: ' bash -x script Line 1: foo=10 Line 2: echo 10 10 Line 3: echo 4 4

How do I print line numbers from a string in Linux?

First use the -n option to print line numbers for a matching string shell: If you need the output on a single line add one more pipe to tr command to remove all new line characters and replace them with single space:

How to automatically detect errors in a script?

If you use set -e, or trap ... ERR to automatically detect errors, note that they have some caveats. It's also harder to include a description of what the script was doing at the time (as you did in your example), though that might be more useful to a regular user than just the line number.


1 Answers

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
like image 159
Charles Duffy Avatar answered Sep 25 '22 10:09

Charles Duffy