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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.