What is the $BASH_COMMAND variable good for?
Answering to the third question: of course it can be used meaningfully in the way at Bash manual clearly hints – in a trap, e. g.:
$ trap 'echo ‘$BASH_COMMAND’ failed with error code $?' ERR
$ fgfdjsa
fgfdjsa: command not found
‘fgfdjsa’ failed with error code 127
$ cat /etc/fgfdjsa
cat: /etc/fgfdjsa: No such file or directory
‘cat /etc/fgfdjsa’ failed with error code 1
Now that Q3 has been answered (correctly, in my opinion: BASH_COMMAND
is useful in traps and hardly anywhere else), let's give Q1 and Q2 a shot.
The answer to Q1 is: the correctness of your assumption is undecidable. The truth of neither of the bullet points can be established, as they ask about unspecified behaviour. By its specification, the value of BASH_COMMAND
is set to the text of a command for the duration of the execution of that command. The spec does not state what its value must be in any other situation, i.e. when no command is being executed. It could have any value or none at all.
The answer to Q2 "If no, how else can the behavior in the above command sequence be explained?" then follows logically (if somewhat pedantically): it is explained by the fact that the value of BASH_COMMAND
is undefined. Since its value is undefined, it can have any value, which is exactly what the sequence shows.
Postscript
There is one point where I think you're indeed hitting a soft spot in the spec. It's where you say:
Even when I do MYVARIABLE=$BASH_COMMAND right at the beginning of my $PROMPT_COMMAND, then MYVARIABLE contains the string MYVARIABLE=$BASH_COMMAND, because an assignment is a command too.
The way I read the bash man page, the bit in italics is not true. The section SIMPLE COMMAND EXPANSION
explains how first the variable assignments on the command line are set aside, and then
If no command name results [in other words, there were only variable assignments], the variable assignments affect the current shell environment.
This suggests to me that variable assignments are not commands (and therefore exempt from showing up in BASH_COMMAND
), like in other programming languages. This would then also explain why there isn't a line BASH_COMMAND=set
in the output of set
, set
essentially being a syntactic 'marker' for variable assignment.
OTOH, in the final paragraph of that section it says
If there is a command name left after expansion, execution proceeds as described below. Otherwise, the command exits.
... which suggests otherwise, and variable assignments are commands too.
An inventive use for $BASH_COMMAND
Recently found this impressive use of $BASH_COMMAND in implementing a macro-like functionality.
This is the core trick of the alias and replaces the use of the DEBUG trap. If you read the part in the previous post about the DEBUG trap, you’ll recognize the $BASH_COMMAND variable. In that post I said that it was set to the text of the command before each call to the DEBUG trap. Well, it turns out it’s set before the execution of every command, DEBUG trap or no (e.g. run ‘echo “this command = $BASH_COMMAND”‘ to see what I’m talking about). By assigning it a variable (just for that line) we capture BASH_COMMAND at the outermost scope of the command, which will contain the entire command.
The author's previous article also provides some good background while implementing a technique using a DEBUG trap
. The trap
is eliminated in the improved version.