External Commands in the Prompt

Bash Prompt HOWTO:
Prev | Chapter 4. External Commands | Next

# 4.2. External Commands in the Prompt

You can use the output of regular Linux commands directly in the prompt as well. Obviously, you don't want to insert a lot of material, or it will create a large prompt. You also want to use a fast command, because it's going to be executed every time your prompt appears on the screen, and delays in the appearance of your prompt while you're working can be very annoying. (Unlike the previous example that this closely resembles, this does work with Bash 1.14.7.)

    [21:58:33][giles@nikola:~]$ PS1="[\$(date +%H%M)][\u@\h:\w]\$ "
    [2159][giles@nikola:~]$ ls
    bin   mail
    [2200][giles@nikola:~]$

It's important to notice the backslash before the dollar sign of the command substitution. Without it, the external command is executed exactly once: when the PS1 string is read into the environment. For this prompt, that would mean that it would display the same time no matter how long the prompt was used. The backslash protects the contents of $() from immediate shell interpretation, so date is called every time a prompt is generated.

Linux comes with a lot of small utility programs like date, grep, or wc that allow you to manipulate data. If you find yourself trying to create complex combinations of these programs within a prompt, it may be easier to make an alias, function, or shell script of your own, and call it from the prompt. Escape sequences are often required in bash shell scripts to ensure that shell variables are expanded at the correct time (as seen above with the date command): this is raised to another level within the prompt PS1 line, and avoiding it by creating functions is a good idea.

An example of a small shell script used within a prompt is given below:

    #!/bin/bash
    #     lsbytesum - sum the number of bytes in a directory listing
    TotalBytes=0
    for Bytes in $(ls -l | grep "^-" | awk '{ print $5 }')
    do
        let TotalBytes=$TotalBytes+$Bytes
    done
    TotalMeg=$(echo -e "scale=3 \n$TotalBytes/1048576 \nquit" | bc)
    echo -n "$TotalMeg"

I used to keep this as a function, it now lives as a shell script in my `~/bin` directory, which is on my path. Used in a prompt:

    [2158][giles@nikola:~]$ PS1="[\u@\h:\w (\$(lsbytesum) Mb)]\$ "
    [giles@nikola:~ (0 Mb)]$ cd /bin
    [giles@nikola:/bin (4.498 Mb)]$

Prev | Home | Next
PROMPT_COMMAND | Up | What to Put in Your Prompt