This section shows how to put various pieces of information into the Bash prompt. There are an infinite number of things that could be put in your prompt. Feel free to send me examples, I will try to include what I think will be most widely used. If you have an alternate way to retrieve a piece of information here, and feel your method is more efficient, please contact me. It's easy to write bad code, I do it often, but it's great to write elegant code, and a pleasure to read it. I manage it every once in a while, and would love to have more of it to put in here.
To incorporate shell code in prompts, it has to be escaped. Usually, this
will mean putting it inside \$(<command>)
so that the output
of command
is substituted each time the prompt is generated.
See Bash Prompt Escape Sequences for a complete list of built-in escape sequences. This list is taken directly from the Bash man page, so you can also look there.
If you don't like the built-ins for date and time, extracting the same
information from the date
command is relatively easy. Examples
already seen in this HOWTO include date +%H%M
, which will put
in the hour in 24 hour format, and the minute. date "+%A, %d %B
%Y"
will give something like "Sunday, 06 June 1999". For a full list
of the interpreted sequences, type date --help
or man
date
.
To determine how many files there are in the current directory, put in
ls -l | wc -l
. This uses wc
wordcount to do a count of
the number of lines (-l) in the output of ls -l
. It doesn't count
dotfiles. If you want to count only files and NOT include symbolic links
(just an example of what else you could do), you could use ls -l | grep
-v ^l | wc -l
. Here, grep
checks for any line beginning with
"l" (indicating a link), and discards that line (-v).
If you want to know how much space the contents of the current directory take up, you can use something like the following:
# The sed command replaces all the spaces with only one space. # cut -d" " -f5 : -d determines a delimiter, which means that (in # this case) a space begins a new column. # -f says to take out a certain column, in this case the fifth one let TotalBytes=0 for Bytes in $(ls -l | grep "^-" | sed -e "s/ \+/ /g" | cut -d" " -f5) do let TotalBytes=$TotalBytes+$Bytes done # The if...fi's give a more specific output in byte, kilobyte, megabyte, # and gigabyte if [ $TotalBytes -lt 1024 ]; then TotalSize=$(echo -e "scale=3 \n$TotalBytes \nquit" | bc) else if [ $TotalBytes -lt 1048576 ]; then TotalSize=$(echo -e "scale=3 \n$TotalBytes/1024 \nquit" | bc) else if [ $TotalBytes -lt 1073741824 ]; then TotalSize=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc) else TotalSize=$(echo -e "scale=3 \n$TotalBytes/1073741824 \nquit" | bc) fi fi fi
Code courtesy of Sam Schmit (id@pt.lu) and his uncle Jean-Paul, who ironed out a fairly major bug in my original code, and just generally cleaned it up.
The tty
command returns the filename of the terminal connected to
standard input. This comes in two formats on the Linux systems I have
used, either "/dev/tty4" or "/dev/pts/2". I have taken to using a more
general solution to this: tty | sed -e "s:/dev/::"
, which removes
the leading "/dev/". Older systems
(in my experience, RedHat through 5.2) returned only filenames in the
"/dev/tty4" format, so I used tty | sed -e "s/.*tty\(.*\)/\1/"
.
An alternative method: ps aux | grep $$ | awk '{ print $7 }'
.
To find out how many suspended jobs you have, use jobs | wc -l | awk
'{print $1}'
. awk
is used to trim the output, which would
otherwise include blank spaces that waste space in a prompt. If you start
netscape from an xterm, this will also be counted. If you want to avoid
that, and only count stopped jobs, use jobs -s
instead. Type
help jobs
for more info on jobs. jobs
will always return
nothing to a pipe in version 2.02 of Bash: this problem is not present in
any other version.
Current load is taken from the uptime
command. What I use at the
moment is uptime | sed -e "s/.*load average: \(.*\...\), .*\...,
.*\.../\1/" -e "s/ //g"
which is clunky in the extreme, but works.
Replacements welcome. uptime
can also be used in a very similar
manner to find out how long the machine has been up (obviously) or how many
users are logged in, and the data could be massaged with sed
to
look the way you want it to.
ps ax | wc -l | tr -d " "
OR ps ax | wc -l | awk
'{print $1}'
OR ps ax | wc -l | sed -e "s: ::g"
. In
each case, tr
or awk
or sed
is used to remove
the undesirable whitespace.
Unix allows long file names, which can lead to the value of $PWD being very long. Some people (notably the default RedHat prompt) choose to use the basename of the current working directory (ie. "giles" if $PWD="/home/giles"). I like more info than that, but it's often desirable to limit the length of the directory name, and it makes the most sense to truncate on the left.
# How many characters of the $PWD should be kept local pwd_length=30 if [ $(echo -n $PWD | wc -c | tr -d " ") -gt $pwd_length ] then newPWD="...$(echo -n $PWD | sed -e "s/.*\(.\{$pwd_length\}\)/\1/")" else newPWD="$(echo -n $PWD)" fi
The above code can be executed as part of PROMPT_COMMAND, and the environment variable generated (newPWD) can then be included in the prompt.
Again, this isn't elegant, but it works (most of the time). If you have a
laptop with APM installed, try power=$(apm | sed -e "s/.*:
\([1-9][0-9]*\)%/\1/" | tr -d " ")
executed from PROMPT_COMMAND to
create an environment variable you can add to your prompt. This will
indicate percentage power remaining.
This one is weird but cool. Rory Toma (rory@corp.webtv.net) wrote to
suggest a prompt like this: : rory@demon ;
. How is this useful?
Well, if you type a command after the prompt (odd idea, that), you can
triple click on that line (in Linux, anyway) to highlight the whole line,
then paste that line in front of another prompt, and the stuff between the
":" and the """ is ignored, like so:
: rory@demon ; uptime 5:15pm up 6 days, 23:04, 2 users, load average: 0.00, 0.00, 0.00 : rory@demon ; : rory@demon ; uptime 5:15pm up 6 days, 23:04, 2 users, load average: 0.00, 0.00, 0.00
The prompt is a no-op, and if your PS2 is set to a space, multiple lines can be cut and pasted as well.
A suggestion from Charles Lepple (clepple@negativezero.org) on setting the window title of the Xterm and the title of the corresponding icon separately (first check out the earlier section Xterm Title Bar Manipulations). He uses this under WindowMaker because the title that's appropriate for an Xterm is usually too long for a 64x64 icon. "\[\e]1;icon-title\007\e]2;main-title\007\]". He says to set this in the prompt command because "I tried putting the string in PS1, but it causes flickering under some window managers because it results in setting the prompt multiple times when you are editing a multi-line command (at least under bash 1.4.x -- and I was too lazy to fully explore the reasons behind it)." I had no trouble with it in the PS1 string, but didn't use any multi-line commands. He also points out that it works under xterm, xwsh, and dtterm, but not gnome-terminal (which uses only the main title). I also found it to work with rxvt, but not kterm.