Archimedes Trajano
Archimedes Trajano

Reputation: 41330

How to change the terminal title to currently running process?

I know how to change the Terminal Window title. What I am trying to find out is how to make bash not zsh write out the currently running process so if I say do

$ ls -lF

I would get something like this for the title

/home/me/curerntFolder (ls -lF)

Getting the last executed command would be too late since the command has executed already, so it won't set the title with the command that was executed.

Upvotes: 5

Views: 10608

Answers (7)

Shilion
Shilion

Reputation: 1

I recently switched my terminal emulator from Konsole to Alacritty and I wanted to simulate Konsole's title bar behavior in Alacritty. I found that adding the following lines to my ~/.bashrc works quite well. If you're using a different terminal emulator, please replace "${TERM}" == "alacritty" in the if statement for your terminal.

if [[ "${TERM}" == "alacritty" ]]; then
    trap 'printf "\033]0;%s : %s — Alacritty\007" "${PWD/#$HOME/\~}" "${BASH_COMMAND%% *}"' DEBUG
    PROMPT_COMMAND='printf "\033]0;%s : bash — Alacritty\007" "${PWD/#$HOME/\~}"'
fi

In above approach, note that

  • ${BASH_COMMAND%% *} truncates the command to the program being run. If you prefer to display the full command, you can use ${BASH_COMMAND} instead.
  • Using %s in the printf statements ensures proper handling of the strings to avoids unexpected output.
  • The trap command dynamically updates the terminal title with the name of the currently running command. For example, running sleep 10 in your home directory gives ~ : sleep — Alacritty in title bar.
  • When no program is running, the title defaults back to ~ : bash — Alacritty, as defined by PROMPT_COMMAND.

Upvotes: 0

markp-fuso
markp-fuso

Reputation: 34554

UPDATE: my previous answer (at end of this post) displays the previous command in the title bar.

Ignoring everything from my previous answer and starting from scratch:

trap 'echo -ne "\033]0;${PWD}: (${BASH_COMMAND})\007"' DEBUG

Running the following at the command prompt:

$ sleep 10

The window title bar changes to /my/current/directory: (sleep 10) while the sleep 10 is running.

Running either of these:

$ sleep 1; sleep 2; sleep 3
$ { sleep 1; sleep2; sleep 3; }

The title bar changes as each sleep command is invoked.

Running this:

$ ( sleep 1; sleep 2; sleep 3 )

The title bar does not change (the trap does not apply within a subprocess call).

One last one:

$ echo $(sleep 3; echo abc)

The title bar displays (echo $sleep 3; echo abc)).


previous answer

Adding to this answer:

store_command() {
  declare -g last_command current_command
  last_command=$current_command
  current_command=$BASH_COMMAND
  return 0
}
trap store_command DEBUG

PROMPT_COMMAND='echo -ne "\033]0;${PWD}: (${last_command})\007"'

Additional reading materials re: trap / DEBUG:

Upvotes: 7

dsimic
dsimic

Reputation: 390

Unfortunately, I was unable to find anywhere some instructions about avoiding the use of raw escape sequences to set the title of a terminal emulator window. Using obscure raw escape sequences isn't great and is one of the reasons why the terminfo database was created, so I got motivated to research it all in detail, to implement setting the window title properly in my ~/.bashrc, and to finally write this answer.

First, here's an excerpt from my ~/.bashrc, which shows the bash code I implemented to set the window title, while using no raw escape sequences:

if [[ "${TERM}" != 'linux' ]]; then
        # Force the terminal type, to work around GUI terminal
        # emulators that set $TERM wrongly to a type that doesn't
        # support status line, e.g. "xterm-256color"

        SL_TERM='xterm-pcolor'
        SL_START="$(TERM=${SL_TERM}; tput tsl)"
        SL_END="$(TERM=${SL_TERM}; tput fsl)"

        SL_CMD='${USER}@${HOSTNAME%%.*} ${PWD/#${HOME}/\~}'
        SL_CMD+='$(STATUS=${?}; [[ ${STATUS} != 0 ]] && echo -n " [ERROR: ${STATUS}]")'

        PROMPT_COMMAND="echo -n \"${SL_START}${SL_CMD}${SL_END}\""
        unset SL_TERM SL_START SL_END SL_CMD
else
        unset PROMPT_COMMAND
fi

The key here is to use the tput(1) utility to generate the required escape sequences, using the terminfo(5) database that describes the capabilities of various terminals and terminal emulators. As you can see in the comment in the bash code above, some terminal emulators actually misbehave a bit, but that can be worked around rather easily.

The two terminal capabilities we're interested in are tsl (to_status_line, move to status line, column #1) and fsl (from_status_line, return from status line). These two capabilities actually produce the raw escape sequences \033]0; and \007, respectively, which you can find mentioned everywhere.

Obviously, the Linux virtual console has no status line capabilities, so the code above configures no status line updates when the shell is running there. The capabilities of each terminal type can be checked rather easily by using infocmp(1M), for example by running infocmp -I linux, infocmp -I xterm-256color, or infocmp -I xterm-pcolor.

Here are also a few versions of the XTerm Control Sequences reference, which are rather hard to locate, listed in the descending order of their readability: 2023 version (HTML), 1994 version (PDF), and 2005 version (HTML).

I hope this will help with demystifying the whole thing a bit.

Upvotes: 0

Omkesh Sajjanwar
Omkesh Sajjanwar

Reputation: 843

For Linux OS Adding following function in bashrc file

Following Steps

  1. Open bashrc file

vi ~/.bashrc

  1. Write a function in bashrc file

    function set-title() {
       if [[ -z "$ORIG" ]]; then
         ORIG=$PS1
       fi
       TITLE="\[\e]2;$*\a\]"
       PS1=${ORIG}${TITLE}
     }

enter image description here

  1. save the file

source ~/.bashrc

  1. call function

set-title "tab1"

enter image description here

Upvotes: 3

RAJ KUMAR NAYAK
RAJ KUMAR NAYAK

Reputation: 21

The easiest way to change the title of the terminal I could think of is to use echo in shell script

echo "\033]0;Your title \007"

And to change open a new tab with new title name is

meta-terminal--tab-t"Your title" 

Upvotes: -2

Archimedes Trajano
Archimedes Trajano

Reputation: 41330

In addition to @markp-fuso's answer, here's how I did it to make it work with Starship.

  function set_win_title() {
    local cmd=" ($@)"
    if [[ "$cmd" == " (starship_precmd)" || "$cmd" == " ()" ]]
    then
      cmd=""
    fi
    if [[ $PWD == $HOME ]]
    then
      if [[ $SSH_TTY ]]
      then
        echo -ne "\033]0; 🏛ī¸ @ $HOSTNAME ~$cmd\a" < /dev/null
      else
        echo -ne "\033]0; 🏠 ~$cmd\a" < /dev/null
      fi
    else
      BASEPWD=$(basename "$PWD")
      if [[ $SSH_TTY ]]
      then
        echo -ne "\033]0; 🌩ī¸ $BASEPWD @ $HOSTNAME $cmd\a" < /dev/null
      else
        echo -ne "\033]0; 📁 $BASEPWD $cmd\a" < /dev/null
      fi
    fi

  }
  starship_precmd_user_func="set_win_title"
  eval "$(starship init bash)"
  trap "$(trap -p DEBUG |  awk -F"'" '{print $2}');set_win_title \${BASH_COMMAND}" DEBUG

Note this differs from the Custom pre-prompt and pre-execution Commands in Bash instructions in that the trap is set after starship init. Which I have noted in a bug.

Upvotes: 9

Ted Lyngmo
Ted Lyngmo

Reputation: 117308

You can combine setting the window title with setting the prompt.

Here's an example using s PROMPT_COMMAND:

tputps () {
    echo -n '\['
    tput "$@"
    echo -n '\]'
}

prompt_builder () {
    # Window title - operating system command (OSC) ESC + ]
    echo -ne '\033]0;'"${USER}@${HOSTNAME}:$(dirs)"'\a' >&2

    # username, green
    tputps setaf 2
    echo -n '\u'

    # directory, orange
    tputps setaf 208
    echo -n ' \w'
    tputps sgr0 0
}

prompt_cmd () {
    PS1="$(prompt_builder) \$ "
}

export PROMPT_COMMAND=prompt_cmd

Upvotes: 2

Related Questions