Reputation: 41330
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
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.%s
in the printf
statements ensures proper handling of the strings to avoids unexpected output.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.~ : bash â Alacritty
, as defined by PROMPT_COMMAND
.Upvotes: 0
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
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
Reputation: 843
For Linux OS Adding following function in bashrc file
Following Steps
vi ~/.bashrc
Write a function in bashrc file
function set-title() { if [[ -z "$ORIG" ]]; then ORIG=$PS1 fi TITLE="\[\e]2;$*\a\]" PS1=${ORIG}${TITLE} }
source ~/.bashrc
set-title "tab1"
Upvotes: 3
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
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
Reputation: 117308
You can combine setting the window title with setting the prompt.
Here's an example using bashs 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