I was also curious to learn more about the inner workings of setting the title of a terminal emulator window, but unfortunately I was unable to find anywhere some instructions or insights about avoiding the use of raw escape sequences to do that. That made me even more curious.
Using obscure raw escape sequences isn't good at all, and it's one of the reasons why the [terminfo database](https://en.wikipedia.org/wiki/Terminfo) was created, so I got motivated to research it all in detail, to implement setting the window title in my `~/.bashrc` with no use of raw escape sequences, and to finally write this answer and share my findings.
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:
```bash
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+='$([[ $? != 0 ]] && echo -n " [ERROR]")'
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)`](https://man.archlinux.org/man/tput.1.en) utility to generate the required escape sequences, using the [`terminfo(5)`](https://man.archlinux.org/man/terminfo.5.en) 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)`](https://man.archlinux.org/man/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](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html) (HTML), [1994 version](https://www.x.org/docs/xterm/ctlseqs.pdf) (PDF), and [2005 version](https://www.xfree86.org/current/ctlseqs.html) (HTML).
I hope this will help with demystifying the whole thing a bit. It makes me really curious why nobody hasn't explained this before, at least somewhere. Maybe simply my Google-fu wasn't strong enough. :)
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](https://en.wikipedia.org/wiki/Terminfo) 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:
```bash
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+='$([[ $? != 0 ]] && echo -n " [ERROR]")'
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)`](https://man.archlinux.org/man/tput.1.en) utility to generate the required escape sequences, using the [`terminfo(5)`](https://man.archlinux.org/man/terminfo.5.en) 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)`](https://man.archlinux.org/man/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](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html) (HTML), [1994 version](https://www.x.org/docs/xterm/ctlseqs.pdf) (PDF), and [2005 version](https://www.xfree86.org/current/ctlseqs.html) (HTML).
I hope this will help with demystifying the whole thing a bit.