You are viewing glyf

entries friends calendar profile Scribbles in the Dark Previous Previous Next Next
Please Visit - This Blog Is Closed. - "This bash shell is now fully operational!"
Sorry about the ads, I can't turn them off.
"This bash shell is now fully operational!"

For many years, I have been a fan of the Z shell. In particular, I loved its programmable completion and many hookable interactive events.

As the years have gone by, however, Bash has slowly re-taken the ground that ZSH originally claimed. Programmable completion, ever more elaborate prompts, and so on became as commonplace in bash configurations as in ZSH. In addition, Bash has had better Unicode support for a long time. The one thing that left ZSH on top of the heap for me was the presence of two hookable events: "precmd" and "preexec", which allowed me to set the title of a ZSH terminal window to be whatever command was currently running. For a variety of reasons, this ability to quickly identify windows has long been immensely useful to me and I was reluctant to give it up.

However, one night a few weeks ago, I was haplessly tab-completing some heinous unicode filename and ... something happened. I'm not really sure what - it may even have been my own fault. However, rm -fr é¢ñ/<tab> somehow became "rm -fr \x00 \x00 \x00 ~" (or something along those lines) and only a very quick control-C saved my home directory.

Knowing that Bash would have Done The Right Thing in this situation thanks to Readline's UTF-8 input support, It was finally time for me to make the switch. I just needed to see if there was any hope of saving my beloved xterm titles on my way over there.

It turns out, there is. Submitted for your approval: zsh-compatible precmd and postcmd support in PURE BASH!

There was apparently a problematic patch to bash at one time which provided similar functionality, but it isn't necessary! You can have zsh-style custom xterm titles in versions of bash all the way back to 2.05b with the above file.

Here's a simple example, which you can use with the above script:

set_xterm_title () {
local title="$1"
echo -ne "\e]0;$title\007"

precmd () {
set_xterm_title "${TERM} - ${USER}@${HOSTNAME} `dirs -0` $PROMPTCHAR"

preexec () {
set_xterm_title "${TERM} - $1 {`dirs -0`} (${USER}@${HOSTNAME})"
jes5199 From: jes5199 Date: December 8th, 2006 11:07 pm (UTC) (Link)
This is extremely cool. Thanks. (Now I have my GNU SCREEN title and my XTERM title set together using readable commands, rather than using screen's terribly conceived auto-titles)
glyf From: glyf Date: December 9th, 2006 02:26 am (UTC) (Link)
Glad you enjoyed it. Spread the word! I have been looking for a way to do this in bash for years, and others looking for a similar hack will likely have a hard time finding it from google... (how did you run across it, anyway?)
jes5199 From: jes5199 Date: December 9th, 2006 02:31 am (UTC) (Link)
I googled for preexec() bash
because I had seen the zsh preexec example in the Screen infodocs, and I didn't see any good reason why that hadn't been ported to bash. I was about to install the patch when I found your post.
rawy From: rawy Date: March 18th, 2007 05:12 pm (UTC) (Link)
Cool news cool ideas! and cool you also
From: williamsmj Date: March 20th, 2007 01:43 am (UTC) (Link)
Can you say a bit more about how you get this to interact with screen correctly. So far, in my ~/.bashrc (right at the end) I have:
. ~/

set_xterm_title () {
    local title="$1"
    case "$TERM" in
        echo -ne "\e]0;$title\007"
        echo -ne "\033k$title\033\134"

precmd () {
    set_xterm_title "${USER}@${HOSTNAME} `dirs -0` $PROMPTCHAR"

preexec () {
    set_xterm_title "$1 {`dirs -0`} (${USER}@${HOSTNAME})"

In my ~/.screenrc I have:

caption always "%{= kw}%-w%{= BW}%n %t%{-}%+w %-= %1` %y.%m.%d %C:%s%a"

lifted from Mark Pilgirm (which is where I found this page, by the way).

Unsurprisingly, this works in an xterm. In screen, the screen title is set correctly, to "top {~} (user@host)" or whatever, but my bash prompt is screwed up. It reads "bembo:~$ ~$", but the cursor is positioned under the second ~, and overwrites is and the final $ as you type. Presumably the problem is with 'echo -ne "\033k$title\033\134"' in my .bashrc, but I can't see it. I'd be very grateful for a quick fix, or a better method!
From: williamsmj Date: March 20th, 2007 01:52 am (UTC) (Link)
bembo is my host, by the way, not the random product of subtly interacting escape codes.
From: williamsmj Date: March 20th, 2007 05:24 pm (UTC) (Link)
For Google's benefit, the fix is to change

echo -ne "\033k$title\033\134"


echo -ne "\033k$title\033\\"
From: georgiajosh Date: June 21st, 2007 04:22 pm (UTC) (Link)


Thanks this is an awesome find, I never would have found this out on my own, Congrats on the discovery.
Thanks for the post.

Josh King Atlanta Center for Cosmetic Dentistry
glyf From: glyf Date: June 21st, 2007 07:39 pm (UTC) (Link)

Re: Awesome

Hi there,

I am going to go out on a limb here and assume your post is legit, but I almost deleted it as spam; you tripped almost every one of my triggers. Just some pointers for next time, your post looks like spam because:

  • it's short
  • it doesn't mention the content of the article specifically
  • it includes a hyperlink to a completely unrelated commercial site
From: lmjog Date: July 11th, 2007 03:09 pm (UTC) (Link)

Question about preexec.bash

Thanks for a great hack to bash!

I've tried to use the precmd & preexec functions used at the bottom of your script, but it seems that I need to setup the variables $SCREEN_RUN_HOST and $SCREEN_HOST somewhere in my .bashrc to get it work correctly.

Could you please share what how you set up those?

glyf From: glyf Date: July 11th, 2007 03:39 pm (UTC) (Link)

Re: Question about preexec.bash

Oh. That's unfortunate. Those variables are part of some pretty gratuitous hacks in my overall setup; I'll try to correct this "module" so that it doesn't require them.
From: lmjog Date: July 11th, 2007 04:08 pm (UTC) (Link)

Re: Question about preexec.bash

If possible if you could just share the info on how you set them. I use a setup with a couple of nested screens myself, and if I can read your script correctly, I like the idea how it presents itself.
glyf From: glyf Date: August 2nd, 2007 07:29 pm (UTC) (Link)

Re: Question about preexec.bash

Sorry for the long delay; I keep thinking I'll have time to eventually clean everything up and do a real release of my whole config.

In the meanwhile, just do this in your shell startup somewhere:
export SCREEN_HOST=`hostname -s`
then in your screenrc,

# Many sshd configurations accept "LC_*" environment variables.  Take advantage
# of that to sneak our environment variables over there.
From: corporal_touchy Date: November 19th, 2007 05:14 pm (UTC) (Link)

very very cool!

no not cool
plain f**king awesome!

this should totally be incorporated into bash by a patch instead of hack

but meanwhile
thanks for the hack! ;)

cool trick with the LC_ vars to shorten the prompts, too!
14 comments or Leave a comment
Glyph Lefkowitz
User: glyf
Name: Glyph Lefkowitz
Back December 2010
page summary