4.16. Preprompt, Pre-execution, and Periodic Commands
bash,
tcsh, and
zsh can run a Unix command, or multiple commands,
before printing each prompt.
tcsh and zsh also can
do something you specify before executing the command
you've typed at a prompt. Finally,
tcsh and zsh can do something
periodically (every n seconds) before whatever
prompt comes next. (Section 4.15 shows how to
execute commands periodically in the original Bourne shell.) These
commands don't have anything to do with setting the
prompt itself, though they can. The command could do some system
checking, reset shell variables, or almost anything that you could
type at a shell prompt. If the commands run slowly,
they'll delay whatever else you're
doing, so keep that in mind.
Let's start with
precmd, the tcsh
alias that's run after your command line is read and
before the command is executed. In zsh, the same
thing is done by the shell function named
preexec. Shell history is available, so you can
use history substitution (Section 30.8) inside the alias or function.
Here's a nice example
adapted from the tcsh manual page: showing the
command line you're running in your
xterm window titlebar. It's ugly
because it has ESC and CTRL-g characters embedded directly in the
alias; I'd rather store the escape sequences in
shell variables, as shown in the xterm titlebar
article (Section 4.8). The
if sets the alias only if you're
using an xterm terminal:
# Show each command line in xterm title bar:
if ($TERM == xterm) alias postcmd 'echo -n "^[ ]2;\!#^G"'
Next,
let's look at running a command periodically.
You'd like to watch the load average by running
uptime (Section 26.4) every
minute, before a prompt. Here's how to do it in
zsh: put code like this in your
.zshrc
file (Section 3.3)
(or just type it at a prompt to try it). The
PERIOD shell variable is the interval, in
seconds, between runs of the periodic function
as shown in the following code:
# Run "uptime" every 60 seconds; put blank line before:
periodic( ) {echo "\n==> $(uptime) <==";}
PERIOD=60
Here's how it looks:
jpeek@ruby$ pwd
/u/jpeek/pt
==> 5:16pm up 4:07, 6 users, load average: 0.22, 0.15, 0.08 <==
jpeek@ruby$ lpr xrefs
jpeek@ruby$ mail -s "xrefs list" jan < xrefs
==> 5:17pm up 4:08, 7 users, load average: 1.29, 0.55, 0.23 <==
jpeek@ruby$
Finally,
here's how to set preprompt commands. These are run
before each shell prompt is printed. In tcsh,
define a precmd alias. In zsh,
define a precmd function. In
bash, store the command(s) in the
PROMPT_COMMAND shell variable.
Let's look at bash this time.
Here's a silly example that I used to have in my
bash setup
file (Section 3.3):
IFS Section
36.23, set Section 35.25, shift
$# Section 36.10
PROMPT_COMMAND='
# Save old $IFS; set IFS to tab:
OIFS="$IFS"; IFS=" "
# Put x in $1, face in $2, explanation[s] in $3[, $4, ...]:
set x `smiley`
# Put face into $face and explanation(s) into $explan:
face="$2"; shift 2; explan="$*"
# Restore shell environment:
shift $#; IFS="$OIFS"'
# Prompt I use (includes the latest $face):
PS1='\u@\h $face '
The first part is a series
of shell commands that are stored in the
PROMPT_COMMAND variable;
they're surrounded by a pair of single quotes
('' '), one on the first line
(after the =) and the other after
IFS is reset. That series of commands is executed
before every prompt. It sets two shell variables,
$face and $explan, with new
values before each prompt is set. The prompt is set on the last line;
it includes the value of $face.
Here's what my screen looked like with this
ridiculous setup. Notice that the prompt keeps changing as the
PROMPT_COMMAND resets $face
and $explan. If I wanted the explanation of a face
I saw as I went along, I could type echo
<">$explan<">:
jerry@ruby :-{) echo "$explan"
normal smiling face with a moustache
jerry@ruby +<||-) vi proj.cc
...
jerry@ruby :-O echo "$explan"
Mr. Bill
Wow!
ohh, big mouth, Mick Jagger
uh oh
jerry@ruby :-) < g++ -Wall proj.cc
...
(It was even more useless than psychoanalyze-pinhead (Section 19.13), but it was fun while it lasted.) Seriously
now, I'll say again: preprompt commands do
not have to be used to set a prompt. You can use
them to do anything. If the commands in
PROMPT_COMMAND -- or any of the other
functions or aliases we've covered -- write to
standard output or standard error, you'll see that
text on your screen, before or after the prompt, at the point where
the commands are executed.
--JP and SJC
| | | 4.15. External Commands Send Signals to Set Variables | | 4.17. Running Commands When You Log Out |
Copyright © 2003 O'Reilly & Associates. All rights reserved.
|
|