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.

dogbane
  • 29,677

3 Answers3

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 :)

simon
  • 1,508
  • 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 07 '13 at 08:17
  • BTW, I just fielded https://stackoverflow.com/questions/48407130/why-is-my-debug-trap-executed-w-content-redirected-in-echo-foo-echo-bar, 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. – Charles Duffy Jan 23 '18 at 17:28
  • 2
    @orschiro, the advice to run the trap command as a separate command, not to assign it to PS1. – Charles Duffy Jan 23 '18 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

Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
  • 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 '11 at 15:47
  • Doesn't work through ssh – abyss.7 Feb 15 '16 at 08:16
  • Also "kills" the completion on "tab" – abyss.7 Feb 15 '16 at 08:32
  • BTW, I just fielded https://stackoverflow.com/questions/48407130/why-is-my-debug-trap-executed-w-content-redirected-in-echo-foo-echo-bar, 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. – Charles Duffy Jan 23 '18 at 17:29
  • Wouldn't it be better to redirect to /dev/tty instead of stderr? – Aaron Digulla Mar 26 '19 at 09: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.

  • BTW, I just fielded https://stackoverflow.com/questions/48407130/why-is-my-debug-trap-executed-w-content-redirected-in-echo-foo-echo-bar, 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. – Charles Duffy Jan 23 '18 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 '20 at 13:47