269 lines
8.7 KiB
HTML
269 lines
8.7 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
|
|
<TITLE>How to change the title of an xterm: Examples for different shells</TITLE>
|
|
<LINK HREF="Xterm-Title-5.html" REL=next>
|
|
<LINK HREF="Xterm-Title-3.html" REL=previous>
|
|
<LINK HREF="Xterm-Title.html#toc4" REL=contents>
|
|
</HEAD>
|
|
<BODY>
|
|
<A HREF="Xterm-Title-5.html">Next</A>
|
|
<A HREF="Xterm-Title-3.html">Previous</A>
|
|
<A HREF="Xterm-Title.html#toc4">Contents</A>
|
|
<HR>
|
|
<H2><A NAME="s4">4. Examples for different shells</A></H2>
|
|
|
|
<P>Below we provide an set of examples for some of the more common shells.
|
|
We start with <CODE>zsh</CODE> as it provides several facilities that
|
|
make our job much easier. We will then progress through increasingly
|
|
difficult examples.
|
|
<P>
|
|
<P>In all the examples we test the environment variable <CODE>$TERM</CODE>
|
|
to make sure we only apply the escapes to xterms. We test for
|
|
<CODE>$TERM=xterm*</CODE>; the wildcard is because some variants (such as
|
|
rxvt) can set <CODE>$TERM=xterm-color</CODE>.
|
|
<P>
|
|
<P>We should make an extra comment about C shell derivatives, such as
|
|
<CODE>tcsh</CODE> and <CODE>csh</CODE>. In C shells, undefined variables are
|
|
fatal errors. Therefore, before testing the variable <CODE>$TERM</CODE>, it
|
|
is necessary to test for its existence so as not to break non-interactive
|
|
shells. To achieve this you must wrap the examples below in something
|
|
like:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
if ($?TERM) then
|
|
...
|
|
endif
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
(In our opinion this is just one of many reasons not to use C shells. See
|
|
<I>
|
|
<A HREF="http://language.perl.com/versus/csh.whynot">Csh Programming Considered Harmful</A></I> for a useful
|
|
discussion).
|
|
<P>
|
|
<P>The examples below should be used by inserting them into the appropriate
|
|
shell initialisation file; i.e. one that is sourced by interactive shells
|
|
on startup. In most cases this is called something like
|
|
<CODE>.<I>shell</I>rc</CODE> (e.g. <CODE>.zshrc</CODE>, <CODE>.tcshrc</CODE>, etc).
|
|
<P>
|
|
<P>
|
|
<P>
|
|
<H2><A NAME="ss4.1">4.1 zsh</A>
|
|
</H2>
|
|
|
|
<P><CODE>zsh</CODE> provides some functions and expansions, which we will use:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
precmd () a function which is executed just before each prompt
|
|
chpwd () a function which is executed whenever the directory is changed
|
|
\e escape sequence for escape (ESC)
|
|
\a escape sequence for bell (BEL)
|
|
%n expands to $USERNAME
|
|
%m expands to hostname up to first '.'
|
|
%~ expands to directory, replacing $HOME with '~'
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
There are many more expansions available: see the <CODE>zshmisc</CODE> man page.
|
|
<P>
|
|
<P>Thus, the following will set the xterm title to
|
|
"<CODE><I>username</I>@<I>hostname</I>: <I>directory</I></CODE>":
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
case $TERM in
|
|
xterm*)
|
|
precmd () {print -Pn "\e]0;%n@%m: %~\a"}
|
|
;;
|
|
esac
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
This could also be achieved by using <CODE>chpwd()</CODE> instead
|
|
of <CODE>precmd()</CODE>. The <CODE>print</CODE> builtin works like
|
|
<CODE>echo</CODE>, but gives us access to the <CODE>%</CODE> prompt escapes.
|
|
<P>
|
|
<P>
|
|
<H2><A NAME="ss4.2">4.2 tcsh</A>
|
|
</H2>
|
|
|
|
<P><CODE>tcsh</CODE> has some functions and expansions similar to those of
|
|
<CODE>zsh</CODE>:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
precmd () a function which is executed just before each prompt
|
|
cwdcmd () a function which is executed whenever the directory is changed
|
|
%n expands to username
|
|
%m expands to hostname
|
|
%~ expands to directory, replacing $HOME with '~'
|
|
%# expands to '>' for normal users, '#' for root users
|
|
%{...%} includes a string as a literal escape sequence
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
<P>
|
|
<P>Unfortunately, there is no equivalent to <CODE>zsh</CODE>'s <CODE>print</CODE>
|
|
command allowing us to use prompt escapes in the title string,
|
|
so the best we can do is to use shell variables (in <CODE>~/.tcshrc</CODE>):
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
switch ($TERM)
|
|
case "xterm*":
|
|
alias precmd 'echo -n "\033]0;${HOST}:$cwd\007"'
|
|
breaksw
|
|
endsw
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
However, this gives the directory's full path instead of using <CODE>~</CODE>.
|
|
Instead you can insert the string in the prompt:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
switch ($TERM)
|
|
case "xterm*":
|
|
set prompt="%{\033]0;%n@%m:%~\007%}tcsh%# "
|
|
breaksw
|
|
default:
|
|
set prompt="tcsh%# "
|
|
breaksw
|
|
endsw
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
which sets a prompt of "<CODE>tcsh% </CODE>", and an xterm title and icon
|
|
of "<CODE><I>username</I>@<I>hostname</I>: <I>directory</I></CODE>". Note that
|
|
the "<CODE>%{...%}</CODE>" must be placed around escape sequences (and cannot
|
|
be the last item in the prompt: see the <CODE>tcsh</CODE> man page for details).
|
|
<P>
|
|
<P>
|
|
<H2><A NAME="ss4.3">4.3 bash</A>
|
|
</H2>
|
|
|
|
<P><CODE>bash</CODE> supplies a variable <CODE>$PROMPT_COMMAND</CODE> which contains a
|
|
command to execute before the prompt. This example sets the title to
|
|
<CODE>username@hostname: directory</CODE>:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
where <CODE>\033</CODE> is the character code for <CODE>ESC</CODE>,
|
|
and <CODE>\007</CODE> for <CODE>BEL</CODE>.
|
|
<P>
|
|
<P>Note that the quoting is important here: variables are expanded in
|
|
<CODE>"..."</CODE>, and not expanded in <CODE>'...'</CODE>. So
|
|
<CODE>$PROMPT_COMMAND</CODE> is set to an unexpanded value, but the
|
|
variables inside <CODE>"..."</CODE> are expanded when
|
|
<CODE>$PROMPT_COMMAND</CODE> is used.
|
|
<P>
|
|
<P>However, <CODE>$PWD</CODE> produces the full directory path. If we want to
|
|
use the <CODE>~</CODE> shorthand we need to embed the escape string in the
|
|
prompt, which allows us to take advantage of the following prompt expansions
|
|
provided by the shell:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
\u expands to $USERNAME
|
|
\h expands to hostname up to first '.'
|
|
\w expands to directory, replacing $HOME with '~'
|
|
\$ expands to '$' for normal users, '#' for root
|
|
\[...\] embeds a sequence of non-printing characters
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
<P>
|
|
<P>Thus, the following produces a prompt of <CODE>bash$ </CODE>, and an xterm
|
|
title of <CODE>username@hostname: directory</CODE>:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
case $TERM in
|
|
xterm*)
|
|
PS1="\[\033]0;\u@\h: \w\007\]bash\\$ "
|
|
;;
|
|
*)
|
|
PS1="bash\\$ "
|
|
;;
|
|
esac
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
Note the use of <CODE>\[...\]</CODE>, which tells <CODE>bash</CODE> to ignore
|
|
the non-printing control characters when calculating the width
|
|
of the prompt. Otherwise line editing commands get confused while
|
|
placing the cursor.
|
|
<P>
|
|
<P>
|
|
<H2><A NAME="ss4.4">4.4 ksh</A>
|
|
</H2>
|
|
|
|
<P><CODE>ksh</CODE> provides little in the way of functions and expansions, so
|
|
we have to insert the escape string in the prompt to have it updated
|
|
dynamically. This example produces a title of
|
|
<CODE>username@hostname: directory</CODE> and a prompt of <CODE>ksh$ </CODE>.
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
case $TERM in
|
|
xterm*)
|
|
HOST=`hostname`
|
|
PS1='^[]0;${USER}@${HOST}: ${PWD}^Gksh$ '
|
|
;;
|
|
*)
|
|
PS1='ksh$ '
|
|
;;
|
|
esac
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
However, <CODE>$PWD</CODE> produces the full directory path. We can remove the
|
|
prefix of <CODE>$HOME/</CODE> from the directory using the <CODE>${...##...}</CODE>
|
|
construct. We can also use <CODE>${...%%...}</CODE> to truncate the hostname:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
HOST=`hostname`
|
|
HOST=${HOST%%.*}
|
|
PS1='^[]0;${USER}@${HOST}: ${PWD##${HOME}/}^Gksh$ '
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
Note that the <CODE>^[</CODE> and <CODE>^G</CODE> in the prompt string are single
|
|
characters for <CODE>ESC</CODE> and <CODE>BEL</CODE> (can be entered in emacs
|
|
using <CODE>C-q ESC</CODE> and <CODE>C-q C-g</CODE>).
|
|
<P>
|
|
<P>
|
|
<H2><A NAME="ss4.5">4.5 csh</A>
|
|
</H2>
|
|
|
|
<P>This is very difficult indeed in <CODE>csh</CODE>, and we end up doing something
|
|
like the following:
|
|
<BLOCKQUOTE><CODE>
|
|
<PRE>
|
|
switch ($TERM)
|
|
case "xterm*":
|
|
set host=`hostname`
|
|
alias cd 'cd \!*; echo -n "^[]0;${user}@${host}: ${cwd}^Gcsh% "'
|
|
breaksw
|
|
default:
|
|
set prompt='csh% '
|
|
breaksw
|
|
endsw
|
|
</PRE>
|
|
</CODE></BLOCKQUOTE>
|
|
|
|
where we have had to alias the <CODE>cd</CODE> command to do the work of
|
|
sending the escape sequence. Note that the <CODE>^[</CODE> and <CODE>^G</CODE> in
|
|
the string are single characters for <CODE>ESC</CODE> and <CODE>BEL</CODE>
|
|
(can be entered in emacs using <CODE>C-q ESC</CODE> and <CODE>C-q C-g</CODE>).
|
|
<P>
|
|
<P>Notes: on some systems <CODE>hostname -s</CODE> may be used to get
|
|
a short, rather than fully-qualified, hostname. Some users with
|
|
symlinked directories may find <CODE>`pwd`</CODE> (backquotes to run the
|
|
<CODE>pwd</CODE> command) gives a more accurate path than <CODE>$cwd</CODE>.
|
|
<P>
|
|
<P>
|
|
<P>
|
|
<HR>
|
|
<A HREF="Xterm-Title-5.html">Next</A>
|
|
<A HREF="Xterm-Title-3.html">Previous</A>
|
|
<A HREF="Xterm-Title.html#toc4">Contents</A>
|
|
</BODY>
|
|
</HTML>
|