Subject: Re: ksh, PS1 and $?
To: Denis Lagno <dlagno@rambler.ru>
From: Greg A. Woods <woods@weird.com>
List: netbsd-users
Date: 04/28/2005 03:26:17
[ On Thursday, April 28, 2005 at 00:44:23 (+0000), Frederick Bruckman wrote: ]
> Subject: Re: ksh, PS1 and $?
>
> 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) '
Most of that is static data that doesn't change (hostname, tty, etc.),
so accessing it with command expansions in every prompt echo is more
than just very silly..... :-)
And the pwd is available as $PWD
Expanding the date can be done with arithmetic and arrays:
####################
# initialize SECONDS to the number of seconds since the last
# local wall-clock midnight hour
#
alias set_secs_to_midnight='SECONDS="$(date '"'"'+3600*%H+60*%M+%S'"'"')"'
set_secs_to_midnight
# We wouldn't normally have to reset $SECONDS since our calculations
# for hours and minutes only need to find the remainder values for the
# seconds/unit since any epoch. However wall-clock time will shift
# when daylight savings time transitions happen. Resetting $SECONDS
# once per hour is probably overkill but will do the job -- it only
# really needs to be done once a day at most in order to catch any
# number of daylight savings time transitions.
#
# The first one in the loop should only sleep to the top of the hour,
# but calculating that would really be overkill!
#
# The extra sub-shell is to prevent the main shell from tracking the
# kill job...
#
#trap 'SECONDS="$(date '+3600*%H+60*%M+%S')"; ( { sleep 3600; kill -14 $$; } & )' 14
#
# start the cycle
#
#kill -14 $$
#
# instead of that just remember to run set_secs_to_midnight after every
# transition!
# expressions to calculate hours, minutes, and seconds since midnight
# given the number of $SECONDS (we ignore the number of days that may
# have passed since that midnight hour)
#
_hh="(SECONDS/3600)%24"
_mm="(SECONDS/60)%60"
_ss="(SECONDS)%60"
# We'll be wanting zero-filled 2-digit expansion for our hours and
# minutes variables
#
typeset -Z2 _h _m
# a magic expression that evaluates the above expressions to set the two
# variables we've configured specially above, and then expands those two
# variables in a standard "HH:MM" 24-hr format to show the current time.
#
_time='${_x[(_m=_mm)==(_h=_hh)]}$_h:$_m'
PS1="$_time $PS1"
####################
The above results in something like the following:
01:49 [1969] $ echo $PS1
${_x[(_m=_mm)==(_h=_hh)]}$_h:$_m [!] $
02:10 [1970] $
(note I didn't invent this trick -- but I don't remember where I learned
it from either! :-)
On any windowing system I put the other stuff in the window title where
it doesn't interfere with command-line editing, and I have a trap that
prints any non-zero status codes:
03:21 [1982] $ trap
trap -- '. $HOME/.kshlogout ; exit $?' EXIT
trap -- 'trap 1 2 3 15; setban' HUP
trap -- 'trap 1 2 3 15; setban' INT
trap -- 'trap 1 2 3 15; setban' QUIT
trap -- 'trap 1 2 3 15; setban' TERM
trap -- '
rc=$?;
if ((ERRNO > 0)); then
EMSG="; errno: $ERRNO"
else
EMSG=""
fi;
print "${0#-}: exit code: $rc$EMSG"
' ERR
Learn all about these and many other magic tricks from the files in here:
ftp://ftp.weird.com/pub/local/dotfiles.tar.gz
--
Greg A. Woods
H:+1 416 218-0098 W:+1 416 489-5852 x122 VE3TCP RoboHack <woods@robohack.ca>
Planix, Inc. <woods@planix.com> Secrets of the Weird <woods@weird.com>