Subject: Re: ksh, PS1 and $?
To: None <netbsd-users@netbsd.org>
From: Frederick Bruckman <fredb@immanent.net>
List: netbsd-users
Date: 04/28/2005 00:44:23
In article <20050427210005.GL25048@chup.gado>,
	Denis Lagno <dlagno@rambler.ru> writes:
> 
> I want to set "dynamic" prompt -- including output of some commands.
> For example:
> 
> export PS1='[$(id -nu)@$(hostname -s) ($(tty | sed s/\\/dev\\///)) $(date "+%H:%M:%S") $(pwd) $?$ '
> 
> It works, but problem is that $? loses its value.  In particular, value in the end of the
> prompt, just before $ is always 0.

"$?" is changed in the expression, but oddly, changing any of the "$()"
components to "false" does not change it.  PS1 is correct if you move
"$?" to the beginning, but still you have the second problem...

> I tried to fix it by using temporary file:
> 
> export RETVAL_BEFORE_PROMPT=`mktemp /tmp/retval_before_prompt.XXXXXXXX`
> export PS1='[$(echo $? > $RETVAL_BEFORE_PROMPT; id -nu)@$(hostname -s) ($(tty | sed s/\\/dev\\///)) $(date "+%H:%M:%S") $(pwd) $(cat $RETVAL_BEFORE_PROMPT; sh -c "exit $(cat $RETVAL_BEFORE_PROMPT)")$ '
> 
> It is better.  Value at the end of the prompt before $ is really return value of previous command.
> But if I try to echo $? it is still always 0.

This is all very silly, but how about this...?

  export PS1='$(_status=$?; echo [$(id -nu)@$(hostname -s) \($(tty | sed s/\\/dev\\///)\) $(date "+%H:%M:%S") $(pwd) $_status$; exit $_status) '

By grabbing the status early, and using "exit" to reassert it at the end
of the pipeline, you avoid the "bug" (and no temporary file is needed).

-- 
Frederick