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

8

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() {
    local 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 trigger an error
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. Commented Jan 23, 2023 at 16:10
  • 2
    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. Commented Jan 23, 2023 at 17:30

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.