Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash - Update terminal title by running a second command

On my terminal in Ubuntu, I often run programs which keep running for a long time. And since there are a lot of these programs, I keep forgetting which terminal is for which program, unless I tab through all of those. So I wanted to find a way to update my terminal title to the program name, whenever I run a command. I don't want to do it manually.

I use gnome-terminal, but answer shouldn't really depend on that. Basically, If I'm able to run a second command, then I can simply use gconftool command to update the title. So I was hoping to find a way to capture the command in bash and update the title after every command. How do I do that?

like image 625
Neo Avatar asked Feb 22 '11 09:02

Neo


People also ask

How do you name xterm?

To assign a unique name to an xterm, use the -T switch. To assign a unique name when minimized, use the -n switch. The bash shell uses the PROMPT_COMMAND variable to set the title, iconified and shell prompt. This overrides the -T and -n switches.


2 Answers

I have some answers for you :) You're right that it shouldn't matter that you're using gnome-terminal, but it does matter what command shell you're using. This is a lot easier in zsh, but in what follows I'm going to assume you're using bash, and that it's a fairly recent version (> 3.1).

First of all:

Which environment variable would contain the current 'command'?

There is an environment variable which has more-or-less what you want - $BASH_COMMAND. There's only one small hitch, which is that it will only show you the last command in a pipe. I'm not 100% sure what it will do with combinations of subshells, either :)

So I was hoping to find a way to capture the command in bash and update the title after every command.

I've been thinking about this, and now that I understand what you want to do, I realized the real problem is that you need to update the title before every command. This means that the $PROMPT_COMMAND and $PS1 environment variables are out as possible solutions, since they're only executed after the command returns.

In bash, the only way I can think of to achieve what you want is to (ab)use the DEBUG SIGNAL. So here's a solution -- stick this at the end of your .bashrc:

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

To get around the problem with pipes, I've been messing around with this:

function settitle () {     export PREV_COMMAND=${PREV_COMMAND}${@}     printf "\033]0;%s\007" "${BASH_COMMAND//[^[:print:]]/}"     export PREV_COMMAND=${PREV_COMMAND}' | ' }  export PROMPT_COMMAND=${PROMPT_COMMAND}';export PREV_COMMAND=""'  trap 'settitle "$BASH_COMMAND"' DEBUG 

but I don't promise it's perfect!

like image 56
simon Avatar answered Sep 21 '22 03:09

simon


Try this:

trap 'echo -ne "\033]2;$(history 1 | sed "s/^[ ]*[0-9]*[ ]*//g")\007"' DEBUG 

Thanks to the history 1 it works even with complicated expressions like:

true && (false); echo $? | cat 

For which approaches relying on $BASH_COMMAND or $@ fail. For example simon's displays:

true | echo $? | cat 

Thanks to Gilles and simon for providing inspiration.

like image 22
John Mellor Avatar answered Sep 21 '22 03:09

John Mellor