Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How do I make trap to return the command that caused an ERR?

$function err_handler() { echo "$0 caused the error"; }

$ trap err_handler ERR

$ grep -ci "failed" test4 &>/dev/null
-bash caused the error

I wanted the output like

grep caused the error

and possibly ( greedy enough ) to have the entire substituted command line. Is it possible ( without any hacks )?

EDIT: I apologize for not mentioning that my shell is KSH.

share|improve this question

2 Answers 2

up vote 4 down vote accepted

Make sure the command history is enabled (off by default for non-interactive shells) and use that:

#!/bin/bash
set -o history
function trapper () {
    printf "culprit: "
    history 1
}

trap trapper ERR

# your errors go here
share|improve this answer
    
This works perfectly for bash, but I am using ksh. I tried the above idea with ksh , replacing history 1 with fc -nl -1 inside my ksh script, but it said "fc: history functions not available" , which I ll post as a separate questions.But, this answer is right. –  user917279 Oct 4 '13 at 7:22

If you're using Bash, you can use the $BASH_COMMAND parameter:

BASH_COMMAND
    The command currently being executed or about to be executed, unless
    the shell is executing a command as the result of a trap, in which case
    it is the command executing at the time of the trap.

A few notes: One, $BASH_COMMAND gives you just the command that failed in compound commands, not the entire command line.

$ function err_handler { echo "error: $BASH_COMMAND" }
$ trap err_handler ERR
$ true blah blah blah && false herp derp
error: false herp derp

Two, a pipeline only fails if the last command fails. It still succeeds if intermediate commands fail but the last command succeeds:

$ echo okay | false herp derp | true lol
# err_handler not called, the last command returned true.

Three, $BASH_COMMAND gives you the unparsed command line, so the first thing on the command line is not necessarily the name of the command in unusual circumstances:

$ false herp derp                       # This is okay.
error: false herp derp
$ {false,herp,derp}                     # An obfuscated way to write `false blah blah`
error: {false,herp,derp}
$ cmd=false
$ $cmd herp derp                        
error: $cmd herp derp
share|improve this answer
    
I am sorry that I should have mentioned the shell as ksh.$BASH_COMMAND works well for bash. –  user917279 Oct 4 '13 at 7:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.