I use bash all the time, but there is one thing that always bugged me
that tcsh had that bash didn't: the ability to get the return code from
the last process (or pipeline) embedded easily in the prompt.
This is possible to do, sure, with PROMPT_COMMAND and so forth, but
it's rather annoying, because running PROMPT_COMMAND actually modifies
PIPESTATUS, and so forth.
Anyway, I added this tiny little patch to parse.y that lets you use \?
(as in $?) in the prompt to get the value of PIPESTATUS:
--- parse.y Tue Mar 27 08:06:12 2001
+++ parse.wjl.y Tue Sep 4 19:37:56 2001
@@ -3587,4 +3587,5 @@
\! the history number of this command
\$ a $ or a # if you are root
+ \? the status of the most recent pipeline exit status
\nnn character code nnn in octal
\\ a backslash
@@ -3605,4 +3606,5 @@
char *temp, octal_string[4];
time_t the_time;
+ ARRAY *pipestatus;
result = xmalloc (result_size = PROMPT_GROWTH);
@@ -3824,4 +3826,17 @@
*t = '\0';
goto add_string;
+
+ case '?':
+ pipestatus = array_cell(find_variable("PIPESTATUS"));
+ if (!pipestatus || array_num_elements(pipestatus) < 1)
+ {
+ temp = xmalloc(2);
+ strcpy(temp,"0");
+ }
+ else
+ {
+ temp = array_to_string(pipestatus," ",0);
+ }
+ goto add_string;
case 'j':
--
Wesley J. Landaker - w...@mindless.com
http://www.landaker.net PGP DSS/DH Key: 0x0F338E07
PGPKey FP: 3AAA 424B B488 198E B68B C0E5 390A BACA 0F33 8E07
You can save $? befare doing anything else, and restore it at the end.
I use this:
function ps1 {
local s="${?#0}" pwd="$PWD"
[ "$hash" = '' ] && pwd="${pwd/#$HOME/~}"
echo -n "$hash${s:+$s:}${HOSTNAME%%.*}:${pwd%/}/ "
return "${s:-0}"
}
PS1='$(ps1)'
hash=
case "$(id)" in (uid=0\(*) hash='#';; esac
paul
Actually, PIPESTATUS is modified by PROMPT_COMMAND, but not by command
substitution in PS1 (in 2.04, anyway). $? is modified by both.
Weird. Chet, is this something we should rely on, or might it be
changed?
paul
If you look at parse.y:execute_prompt_command(), it takes pains to
preserve $? around the command's execution. A trivial test:
PROMPT_COMMAND=false
true
echo $?
echos `0' for me, but I have no command substitutions in my prompt.
Command substitution is supposed to affect $?, according to POSIX.2,
if, after the various word expansions, no command is executed. I
think it's wrong to have command substitutions in the prompt strings
affect $?, though, so I'm going to change parse.y:decode_prompt_string()
to save and restore $? around the word expansions.
As for PIPESTATUS, I will change things so that it won't change as
the result of executing $PROMPT_COMMAND.
The end result should be that neither $PROMPT_COMMAND nor prompt string
expansion change $? or $PIPESTATUS.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
( ``Discere est Dolere'' -- chet)
Chet Ramey, CWRU ch...@po.CWRU.Edu http://cnswww.cns.cwru.edu/~chet/
I get the same:
bash-2.04$ echo $PS1
\s-\v\$
bash-2.04$ PROMPT_COMMAND=false
bash-2.04$ true
bash-2.04$ echo $? $PIPESTATUS
0 1
> The end result should be that neither $PROMPT_COMMAND nor prompt string
> expansion change $? or $PIPESTATUS.
Woohoo. For now, my new prompt is:
hash_=
case "$(id)" in ('uid=0('*) hash_='#';; esac
function ps1 {
local -a ps_=("$?" "${PIPESTATUS[@]}")
local pwd_="$PWD" psstr_='' i_
for i_ in "${ps_[@]}"; do psstr_="$psstr_$i_:"; done
case "$psstr_" in
(*[^0:]*) :;;
(*) psstr_='';;
esac
[ "$hash_" = '' ] && pwd_="${pwd_/#$HOME/~}"
echo -n "$hash_$psstr_${HOSTNAME%%.*}:${pwd_%/}/ "
return "${ps_[0]}"
}
PS1='$(ps1)'
paul