The Csh-style !:0
history expansion is an interactive feature. You can use the command history -p "!:0"
to execute it in a script context, though (even when you have set +H
, like most sane people have); but executing it inside PROMPT_COMMAND
or the prompt itself is highly unwieldy. (When I tried, it would show me the penultimate command, or something from within the PROMPT_COMMAND
scriptlet itself.)
Borrowing from https://stackoverflow.com/a/6110446/874188 (currently the accepted answer to Echoing the last command run in Bash?) I would go with
trap 'prompt_previous_command=$prompt_this_command; prompt_this_command=$BASH_COMMAND' DEBUG
PS1='$([[ ${prompt_previous_command%%\ *} == "cd" ]] && echo "(${PWD/$HOME/~})")[jobs: \j] \> '
It is unfortunate that echo "\\w"
doesn't produce the expanded value in this context; ${PWD/$HOME/~}
is a reasonable approximation, although there are corner cases where it gets it wrong.
... Perhaps a less confusing approach is to set the value in the trap already:
trap 'prompt_previous_command=$prompt_this_command
prompt_this_command=$BASH_COMMAND
[[ "${prompt_previous_command%%\ *}" == "cd" ]] &&
prompt_cwd="(\\w)" || prompt_cwd=""
PS1="$prompt_cwd[jobs: \\j] \\> "' DEBUG
Many Bash add-ons want to hook into your PROMPT_COMMAND
and might sabotage any attempt to reserve it for youself; of course, this approach has a similar problem if you have something else in your system which relies on the DEBUG
trap for something.
To make this work for pushd
/ popd
and aliases etc too, here's an adaptation of Dan's excellent answer:
trap 'case ${prompt_prev_pwd-$PWD} in
"$PWD") PS1="[jobs \\j] > ";;
*) PS1="(\\w)[jobs: \\j] > ";;
esac
prompt_prev_pwd=$PWD' DEBUG