4

I'm using the -e flag.

Usage:

#!/bin/bash -e

Explained:

-e      Exit immediately if a simple command (see SHELL GRAMMAR above) exits with a non-zero status

When a command in the script fails, the script exits and doesn't continue to execute the rest of the commands, which is exactly what I want.

But, the failure contains just the info that the failed command chooses to disclose.

Sometimes the failed command is very complicated, like a curl with many headers.

How do I print the failed command? I mean, immediately after it failed.

I know I can use the -x bash flag but it will print all of the executed commands. I'd like to see just the failed one.

2 Answers 2

5

You can use a trap to identify the failing command (and its line number). Here's an example

#!/bin/bash -e
# This script can be used to fail intentionally and exit

# Declare an error handler
trapERR() {
    ss=$? bc="$BASH_COMMAND" ln="$BASH_LINENO"
    echo ">> Failing command is '$bc' on line $ln and status is $ss <<" >&2
    exit $ss
}

# Arrange to call trapERR when an error is raised
trap trapERR ERR    

# Start here
date
echo 'hello, world'
#sleep rt    # Remove the leading comment to 
echo 'all done'
exit 0

Successful completion:

23 Jan 2023 15:58:03
hello, world
all done

Remove the comment in front of the sleep so that you introduce an error

23 Jan 2023 15:58:34
hello, world
sleep: invalid time interval ‘rt’
Try 'sleep --help' for more information.
>> Failing command is 'sleep rt' on line 12 and status is 1 <<
0
1

Find which command is failing, add set -x before it, run the script again.

If you do not know which command is failing - add echo 1, echo 2, etc between commands - it will show you where the bug is.

Just add -x into the script, and look at the last lines of output. You do not have to read the whole output.

2
  • It's a command in a command. I can't just rerun it. There are situations where the next run would look different then the failed run, e.g. timestamps. Jan 23, 2023 at 16:10
  • 1
    Any "command in a command" can be split into several independent commands. Timestamp is a data, not a part of a command. You are looking for excuses to avoid debugging.
    – White Owl
    Jan 23, 2023 at 17:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .