Bash Prompt #3: Disk Free Widget

Bash Prompt Index

UPDATE: If all you want is a functional widget, look at disk-free widget, take 2 - that's a better version. But if you're interested in the code, this is a better place to start.

I think what's always intrigued me about Bash Prompts is the question of how much information I can pack into the tiniest possible space. Many people spend inordinate amounts of time looking at the prompt every day, and any information it can provide is information you don't have to spend time looking up. A common default Bash prompt looks like this:

username@hostname:/path/to/folder$

and that's a good start, but we can do so much more. A couple days ago I posted a disk free TUI script, which was at least partly motivated by the desire to get df info into a prompt. Here's what I came up with:

bash-5.0$ source dfstoplight_circle
bash-5.0$ export PS1="\$(df_stoplight) \u@\h:\w\$ "
○◐○● giles@sli7-f:/home/giles/tmp$

When you create severely condensed information, explanation is always required - an explanation that the prompt user has to store permanently in their head. What you're seeing is that I have four mount points on the system in question, and that two of them (the open circles) fall below a set threshold. In this case, 70% full. The second disk, the half-filled circle, indicates that one of the mount points is between threshold values (70% and 90%). The fourth circle is completely filled, showing that one mount point is above 90% capacity. Its impossible to tell which mount point is which from this representation - but this is simply a warning tool that will remind you to use another tool (like the TUI script I linked above, although df would work fine too) to examine your local HDs. Here's the code for the function used:

# filename: dfstoplight_circle

# Adjust these thresholds to your own tastes:
df_okay=70     # percentage
df_warning=90

df_stoplight () {
    while read -r mountpoint
    do
        percent=$( df --output=pcent "${mountpoint}" | tail -n +2 | tr -d '%' )
        if [ ${percent} -gt ${df_warning} ]
        then
            echo -n "●"
        elif [ ${percent} -gt ${df_okay} ]
        then
            echo -n "◐"
        else
            echo -n "○"
        fi
    done < <( lsblk --output MOUNTPOINT --noheadings | grep -v '^$' | grep -v '[SWAP]' ; mount | grep " cifs " | awk '{ print $3 }' )
}

Some notes about this: if you don't understand the program, look at the dissection of dft which describes how this code works. Those three specialty characters, ●, ◐, ○ - are probably font-dependent. They should work with most modern TrueType Fonts (I have opinions about those too). If they don't appear in your terminal, replace them with a character that does. If you're a Vim user, you can use :digraphs in your editor to see an extensive list of specialty characters.

Personally, I'm a fan of using colour in the prompt to get attention. Many people think of colours in their prompts as part of a theme, and appearance / colour co-ordination is more of a priority than immediate attention. That's a matter of personal choice - I'm just warning you that my choice is loud. This script is very similar to the previous one:

df_stoplight_char="●"
df_okay=70     # percentage
df_warning=90

green='\001\033[38;5;010m\002'
yellow='\001\033[38;5;011m\002'
red='\001\033[38;5;009m\002'
nocolour='\001\033[0;0m\002'

df_stoplight () {
    while read -r mountpoint
    do
        percent=$( df --output=pcent "${mountpoint}" | tail -n +2 | tr -d '%' )
        if [ ${percent} -gt ${df_warning} ]
        then
            echo -en "${red}${df_stoplight_char}${nocolour}"
        elif [ ${percent} -gt ${df_okay} ]
        then
            echo -en "${yellow}${df_stoplight_char}${nocolour}"
        else
            echo -en "${green}${df_stoplight_char}${nocolour}"
        fi
    done < <( lsblk --output MOUNTPOINT --noheadings | grep -v '^$' | grep -v '[SWAP]' ; mount | grep " cifs " | awk '{ print $3 }' )
}

This uses the filled circle in three colours to show your mount points as green (less than 70% full), yellow (70-90% full), and red (more than 90% full).

One strange caveat I cannot explain: when I use this - the coloured version - in a totally clean shell, I end up with line wrap problems (a classic gaffe discussed in Bash Prompt Colours that should be handled by escape sequences incorporated in these scripts: and in fact it works fine in any other terminal, except the "totally clean shell."