[Semibug] Crazy unix shell prompts

Nick Holland nick at holland-consulting.net
Wed Dec 28 23:10:22 EST 2022

I tripped across an idea recently which I'm not sure if
it is brilliant or evil.  But I kinda like it.

Standard unix shell prompt is a $ or # (or a number of
other things, if you like unusual shells).  Every operating
system I've used in the last 40 years has some kind of
prompt...but that's not exactly a requirement.  And most of
us start cramming other info into the prompt, for example,
my standard prompt has grown to three lines -- a blank line,
username at hostname, then the full path and the $ or #.

    <this line intentionally left blank for spacing>
nick at dbu1.in.nickh.org
/bu/hc1/2022-12-24/archive #

(and yes, I get it, a lot of people think my multi-line
command prompts are evil enough already.  If you are in
that camp, you might want to stop reading, or even better,
delete this message now before going on.)

(you were warned)

The suggestion was...put a newline at the end of your PS1
prompt, so that when you copy and paste to re-run a command
(or run it in another window), you don't have to un-select
the $ or # (and everything else you put in).

Huh.  So a command line might look like this:

nick at dbu1.in.nickh.org /bu/hc1/2022-12-24/archive #
<type your command here>

Well, I don't recall if the rest was in the original source
of the message or if I came up with the rest myself...

Make the first character of the prompt line a #, so when
you copy and paste, the username and stuff is a comment.
But then you have to do the same for the PS2 (continuation
prompt).  Ok, so I did.  But I didn't like having a "#" at
the beginning of every command line, because that makes it
look like I'm running as root...so (whoa. slippery slope
here) use a few color changes to make the "#" the
terminal background color.  Ok, so now I have a multi-line
multi-color PS1 with nothing in front of the command I'm
typing.  I warned you.

So now, I have something like this:
  export PS1='\n'$(tput setf 7)#$(tput setf 0)'\$\$\$ \u @ \h \w \$\n'
  export PS2="$(tput setf 7)#$(tput setf 0)>\n"

So now, if I cobble together a few lines that I might wish
to run again via copy/paste or even put into a shell script,
it might look like this:

     #$$$ nick @ hc1 ~ $
     PS3="Pick a motorcycle -> "

     #$$$ nick @ hc1 ~ $
     select M in FLTC K1200LT K100RT BuellBlast; do
     echo $M
     1) FLTC
     2) K1200LT
     3) K100RT
     4) BuellBlast
     Pick a motorcycle -> 3
     Pick a motorcycle -> ^C

     #$$$ nick @ hc1 ~ $

except...the leading "#" are mostly greyed out and ALMOST
indistinguishable from the background.

And now, if I want to re-run this, I can copy and paste the
entire block -- including the prompt lines! -- again and re-run
it or run it somewhere else, or even copy and paste into a
script, then just delete out the prompt lines (dd is quicker than
moving to the right spot and deleting characters)

Oh, btw.  the ksh/bash "select" command is way cool. But that's
a different topic.  I just stuck it in here because, well, I could.

Explanation of the prompt commands:
  export PS1='\n'$(tput setf 7)#$(tput setf 0)'\$\$\$ \u @ \h \w \$\n'
  export PS2="$(tput setf 7)#$(tput setf 0)>\n"

"export" because we want this variable to impact everything
invoked by this shell, not just this shell.
PS1 is the default "Enter your command here" prompt.
    '\n' -- literal newline
    $(tput setf 7) -- set the font color to 7 (grey, on my white background)
       (execute the tput command with those options, embeds an esc sequence)
    #  -- make this line a "comment" if copied and pasted and re-run (but grey!)
    $(tput setf 0) -- set font color back to 0 (black)
    '\$\$\$' -- either $ for normal user or # for root.  Repeated because, well,
        I don't want to take that # as a "you are running as root" here.
    \u -- username
    @ -- literal @ symbol.  Spaces around it because I don't want it look like e-mail.
    \n -- hostname
    \w -- working directory
    \$ -- because the three earlier $ or # weren't enough.
PS2 is the continuation prompt, and PS3 is the prompt used by select.
Some things are surrounded by single quotes to keep them unexpanded,
other things like the PS2, are expanded and stored as escape sequences
rather than running tput every time a PS2 prompt is displayed.

Enjoy. Or don't.  Honestly, I'm not sure if I like this yet, but I
think I do.  Figured I'd share this idea...

Tested on OpenBSD ksh (pdksh) and linux bash.


More information about the Semibug mailing list