26

My Bash Prompt is currently setting the xterm titlebar using the following sequence:

PS1='\033]0;\u@\h>\w\007'

Is there an easy way to display the current command in the titlebar. For example, if I am tailing a file using tail -f foo.log, I want my titlebar to say tail -f foo.log.

3 Answers 3

20

Basically, you need:

trap 'printf "\033]0;%s\007" "${BASH_COMMAND//[^[:print:]]/}"' DEBUG

at the end of your .bashrc or similar. Took me a while to work this out -- see my answer here for more information :)

3
  • Thanks for this solution simon! However, when adding this to my .bashrc after each command in my shell I get this output 0;%s@%s:%s" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}. I assume that I can suppress this output by assigning the trap command to PS1? However, PS1=trap 'echo -ne "\033]0;$BASH_COMMAND\007"' DEBUG does not work. It leads to the error bash: echo -ne "\033]0;$BASH_COMMAND\007": command not found.
    – orschiro
    Dec 7, 2013 at 8:17
  • BTW, I just fielded stackoverflow.com/questions/48407130/…, asked presumably as a result of this advice being applied. The trap should be writing to stderr or to the TTY directly, not to stdout. Jan 23, 2018 at 17:28
  • 2
    @orschiro, the advice to run the trap command as a separate command, not to assign it to PS1. Jan 23, 2018 at 17:29
13

(Inspired by this SU answer)

You can combine a couple bash tricks:

  • If you trap a DEBUG signal, the handler is called before each command is executed
  • The variable $BASH_COMMAND holds the currently executing command

So, trap DEBUG and have the handler set the title to $BASH_COMMAND:

trap 'printf "\033]0;%s\007" "${BASH_COMMAND//[^[:print:]]/}" >&2' DEBUG

This will keep the title changed until something else changes it, but as long as your $PS1 stays the same it won't be a problem -- you start a command, the DEBUG handler changes the titlebar, and when the command finishes bash draws a new prompt and resets your titlebar again.

A useful tip found here (also where that SU answer came from) is to include:

set -o functrace

This will make bash propagate the DEBUG trap to any subshells you start; otherwise the titlebar won't be changed in them

5
  • ha! same answer at exactly the same time! +1 for handling subshells, but do you have any answer to the pipes problem? (see my link to the SO question)
    – simon
    Mar 10, 2011 at 15:47
  • Doesn't work through ssh
    – abyss.7
    Feb 15, 2016 at 8:16
  • Also "kills" the completion on "tab"
    – abyss.7
    Feb 15, 2016 at 8:32
  • BTW, I just fielded stackoverflow.com/questions/48407130/…, asked presumably as a result of this advice being applied. The trap should be writing to stderr or to the TTY directly, not to stdout. Jan 23, 2018 at 17:29
  • Wouldn't it be better to redirect to /dev/tty instead of stderr? Mar 26, 2019 at 9:26
3

I worked around my own solution from various posts around. This creates a title containing user, hostname, pwd, tty and currently executed command (for bash).

This looks like this (no command being executed):

.:[user@hostname:/home/user][pts/10]:.

And like this (executing a command):

.:[user@hostname:/home/user][pts/10] {tail -F /var/log/syslog}:.

Somewhere in the .bashrc, i extended PS1:

# set the terminals title. This is the "post-command" part,
# need to use a trap for pre-command (to add the command line to the title)
PS1+="\[\033]2;.:[\u@\h:\$PWD] [$(tty | cut -b 6-)]:.\007\]"

Adds the current command, using history 1 and trap:

# set a fancy title (this is pre-command, in PS1 is after-command (to reset command)
trap 'echo -ne "\033]2;.:[${USER}@${HOSTNAME}:${PWD}] [$(tty | cut -b 6-)] {$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")}:.\007"' DEBUG

Feel free to adopt to your needs.

2
  • BTW, I just fielded stackoverflow.com/questions/48407130/…, asked presumably as a result of this advice being applied. The trap should be writing to stderr or to the TTY directly, not to stdout. Jan 23, 2018 at 17:29
  • This is a quite good solution. The only downside is that the path won't update immediately after a cd, it will take one more command. Change ]2; to ]0; in order to set the icon name too.
    – Quasímodo
    Jan 30, 2020 at 13:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .