Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PATCH: Add \? to get PIPESTATUS information in the prompt

53 views
Skip to first unread message

Wesley J Landaker

unread,
Sep 4, 2001, 9:39:03 PM9/4/01
to
Hello Bash-Bug person/people, =)

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

Paul Jarc

unread,
Sep 4, 2001, 9:46:21 PM9/4/01
to
"Wesley J Landaker" <w...@mindless.com> wrote:
> 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.

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

Paul Jarc

unread,
Sep 5, 2001, 1:55:35 PM9/5/01
to
I wrote:
> "Wesley J Landaker" <w...@mindless.com> wrote:
>> 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.
>
> You can save $? befare doing anything else, and restore it at the end.

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

Chet Ramey

unread,
Sep 6, 2001, 11:31:14 AM9/6/01
to

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/

Paul Jarc

unread,
Sep 6, 2001, 12:08:29 PM9/6/01
to
Chet Ramey <ch...@nike.ins.cwru.edu> wrote:
> PROMPT_COMMAND=false
> true
> echo $?
>
> echos `0' for me, but I have no command substitutions in my prompt.

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

0 new messages