Random notes from mg

a blog by Marius Gedminas

Marius is a Python hacker. He works for Programmers of Vilnius, a small Python/Zope 3 startup. He has a personal home page at http://gedmin.as. His email is marius@gedmin.as. He does not like spam, but is not afraid of it.

Fri, 10 Mar 2006

Bash prompts: showing the command in the window title

I've been using Linux for almost 10 years now, so I'm used to the command line. Most of the windows in my GNOME desktop are GNOME Terminals. And when you have many of them, you'd like to distinguish them somehow in the window list or window selector applets.

My .bashrc specifies a $PROMPT_COMMAND that sets the username, hostname and the current working directory in the title bar. I can therefore distinguish root terminals and remote terminals (ssh rules), and terminals where I work on different projects in different directories. Until recently I couldn't, however, distinguish the terminal which was running Zope 3 from a terminal which was running functional tests from a terminal which was running an svn update.

For a long time I wanted to see the currently executing command in a terminal title. I always thought this was impossible with bash. David Pashley proved me wrong. I had to change his recipe a little bit, because it interferes with $PROMPT_COMMAND in a nasty way. Here's my .bashrc now:

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'

    # Show the currently running command in the terminal title:
    # http://www.davidpashley.com/articles/xterm-titles-with-bash.html
    show_command_in_title_bar()
    {
        case "$BASH_COMMAND" in
            *\033]0*)
                # The command is trying to set the title bar as well;
                # this is most likely the execution of $PROMPT_COMMAND.
                # In any case nested escapes confuse the terminal, so don't
                # output them.
                ;;
            *)
                echo -ne "\033]0;${USER}@${HOSTNAME}: ${BASH_COMMAND}\007"
                ;;
        esac
    }
    trap show_command_in_title_bar DEBUG
    ;;
*)
    ;;
esac
posted at 10:02 | tags: | permanent link to this entry | 7 comments
Thank you.

David's article helped me get the current running command as a title for my window in GNU-Screen. But it always resulted in extra quotation mark before the prompt. I could not figure out the reason on the solution for this for a long time now. Today your blog article helped resolve that.

Regards,
Srirang G Doddihal
(Brahmana)
posted by Srirang G Doddihal at Mon Jul 20 16:18:12 2009
I've been using this trick for a while and really like it. But today I discovered that it breaks rvm: https://rvm.io/rvm/install/

For example:
$ rvm install 1.9.2

... you get errors like "Unknown ruby interpreter string component: '^[]0;pw'.
Could not detect ruby version/name for installation, please be more specific."

Somehow the prompt command is getting seen by rvm as part of its argument.

rvm consists of a large set of bash functions and I do'nt know how it works. Posting this here to help anybody who finds this via google. I'm currently working around by doing rvm from a plain old console, not under X.
posted by Paul at Thu Jun 14 00:18:37 2012
Thank. This was exactly what I was looking for
posted by Bawolff at Fri Jan 4 10:40:51 2013
using this for Lxterminal and i3 desktop, it works.
http://i3wm.org/docs/userguide.html#_using_i3
posted by success on 2013 too at Sat Jan 26 02:03:28 2013
My prompt and prompt_command variables are sufficiently complex to require a more...robust way to detect which command the user ran and which commands are automated:

COMMAND_LOCK_FILE=$(tempfile)
chmod u-w $COMMAND_LOCK_FILE
export PS1="$PS1$(chmod u+w $COMMAND_LOCK_FILE)"
export PROMPT_COMMAND="NOUSERCOMMAND=true true ${PROMPT_COMMAND:+ ; $PROMPT_COMMAND}"
show_command_in_title_bar()
{
  case "$BASH_COMMAND" in
    *\033]0*)
      # The command is trying to set the title bar as well;
      # this is most likely the execution of $PROMPT_COMMAND.
      # In any case nested escapes confuse the terminal, so don't
      # output them.
      ;;
    NOUSERCOMMAND=true*)
      chmod u-w $COMMAND_LOCK_FILE
      ;;
    *)
      if [[ -w $COMMAND_LOCK_FILE ]]; then
        echo -ne "\033]0;${BASH_COMMAND}...\007"
        chmod u-w $COMMAND_LOCK_FILE
      fi
      ;;
  esac
}
trap show_command_in_title_bar DEBUG

I use the write permission on a temporary file as a communication mechanism (lol!), execute a command at the end of PS1's evaluation to determine when the user is able to execute a command, and the beginning of PROMPT_COMMAND to determine when the user just hit 'return' without a command. This should work for Paul's rvm case also.

Props to anyone who makes it simpler!
posted by Chris at Wed Jun 26 17:51:31 2013
Just a heads-up: BASH_COMMAND may contain escape sequences that you don't want "echo -ne" to parse. I learned this the hard way when smbclient -U yadda/yadda... '\\mymachine\c$' wouldn't show any output or prompts until it finished (\c means "suppress further output" which prevents the closing \007 from being printed).

So, a suitable replacement would be:
  echo -ne "\e]0;"
  echo -n "$BASH_COMMAND"
  echo -ne "\007"
posted by ariel cornejo at Mon May 5 06:56:02 2014
Thank you, ariel!  I fixed it in a different way (by using printf instead of echo -e).
posted by Marius Gedminas at Tue May 13 16:55:26 2014

Name (required)


E-mail (will not be shown)


URL


Comment (some HTML allowed)