Developers’ Weblog

Sponsored by
HostEurope Logo

Developers’ Weblog

⚠ This page contains old, outdated, obsolete, … historic or WIP content! No warranties e.g. for correctness!

All 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

8 Useful and Interesting Bash^Wmksh Prompts

2009-09-10 by tg@
Tags: mksh snippet

smultron, MidnightBSD developer and project member, and graphician / art master for the MidnightBSD Korn Shell (among other things), has pointed me to a blog article: 8 Useful and Interesting Bash Prompts and asked for an mksh(1) translation. These will not be minimalistic (I can do quite some things), but focus on containing no control characters or other things not easily cut-and-past'able. Made more readable, too.

Small note: all mksh examples assume the following "setup code" in front of the PS1=... line. Yes, PS1 is set twice (makes the code more readable and perform better). Most of this is from the mksh(1) manpage or dot.mkshrc and relatively portable, which is why some things seem more complicated than needed. They do, however, use some rather recent mksh features; if there's real interest in making it work with, say, Debian etch mksh R28, eMail me. Note: that → character is a literal Tab (the "[→·]" Tab-Space occurs often).

	ca=$(print -n '\001'); ce=$(print -n '\033'); cm=$(print -n '\r')
	: ${HOSTNAME:=$(ulimit -c 0; hostname -s 2>&-)}
	[[ $HOSTNAME = @(localhost|*([→·])) ]] && \
	    HOSTNAME=$(ulimit -c 0; hostname 2>&-)
	: ${USER:=$(ulimit -c 0; id -un 2>&- || print \?)}
	if (( USER_ID )); then PS1='$'; else PS1='#'; fi

	function twd {
		typeset d=${PWD:-?} p=~

		[[ $p = ?(*/) ]] || d=${d/#$p/~}
		print -nr -- "$d"
	}

If you do not need exactly the effect of "\w" (tilde unexpansion), use $PWD ipv $(twd) below. Note that $USER and $HOSTNAME are usually evaluated only once; escape them if you need it evaluated every time.

  1. Show Happy face upon successful execution
    	bash$ PS1="\`if [ \$? = 0 ]; then
    		echo \[\e[33m\]^_^\[\e[0m\]
    	else
    		echo \[\e[31m\]O_O\[\e[0m\]
    	fi\`[\u@\h:\w]\$ "
    
    	mksh$ PS1="$ca$cm"'$(if (( $? )); then
    		print "'"$ca$ce[31m$caO_O$ca$ce[0m$ca"'"
    	else
    		print "'"$ca$ce[33m$ca^_^$ca$ce[0m$ca"'"
    	fi)'"[$USER@$HOSTNAME:\$(twd)]$PS1 "
    

    I do think Unicode makes things more fun though:
    	mksh$ PS1="$ca$cm$ca$ce["'$(if (( $? )); then
    		print "'"31m$ca☹"'"
    	else
    		print "'"33m$ca☺"'"
    	fi)'"$ca$ce[0m$ca[$USER@$HOSTNAME:\$(twd)]$PS1 "
    
  2. Change color on bad command
    Coming soon... colour changes are okay, but I wonder why anyone would want the history number. I've got to discuss this a little, and think about ways to use such information with mksh, and if I really want to transcribe the prompts 1:1 (it's possible by just incrementing a counter, but, hey, you don't want that). This is actually a csh feature, and who'd really use csh? I'm on my 80486DLC notebook right now, so my debugging methods are a little limited, but I promise a larger article later. I just needed to get started.

This article will be updated in-place.

MirBSD Logo