Make Your Tmux Status Bar 100% Better With Bash
Published: 2021-02-20 23:02:33


This article has been re-written 

[Make Your Status Line 100% Better With Bash](https://dev.to/brandonwallace/make-your-tmux-status-line-100-better-with-bash-mgf)

Did you know that you can easily have a Bash script display information on the Tmux status bar? Because of that the possibilities are almost endless. You can display all sorts of valuable information such as:

Included in this article:

* Hostname
* IP address
* Netmask
* Memory usage
* Memory total
* CPU temperature
* System load
* Battery meter
* VPN status
* Time
* Date

Not included in article:

* Weather report
* Gateway
* Git status

I will show you how to create a modular Bash script to display useful information in the status bar. There are a lot of plug-ins you could install for Tmux but engineering things yourself is a lot of fun. I will create a separate function for each status bar item to make the script modular, that way we will only call the functions that we need.

Here is the default status bar.

![tmux-default-status-bar.png](https://i.postimg.cc/9Q9fM9YJ/tmux-default-status-bar.png)

Here is the status bar customized.

![tmux-status-bar-improved.png](https://i.postimg.cc/0QPGZPN1/tmux-status-bar-improved.png)

## Requirments

* lm-sensors
* bc
* acpi

Check your Tmux version. I am using version 3.1.

```bash
$ tmux -V

# Output
tmux 3.1c
```

If you do not have a .tmux.conf create one in your home directory. 

```bash
$ touch .tmux.conf
```

In the .tmux.conf make sure you have the following lines.

```bash
# Status bar
set -g status on
set -g status-interval 1
set -g status-justify centre # Careful! It is spelled centre not center.
set -g status-style fg=white,bg=black

# Highlight the current window.
setw -g window-status-current-style fg=white,bg=red,bright

# Status Bar Left side
set -g status-left-length 50
set -g status-left-style default
set -g status-left "#h #( ~/.tmux/left_status.sh )"

# Status Bar Right side
set -g status-right-length 40
set -g status-right-style default
set -g status-right "#( ~/.tmux/right_status.sh )"
```

Make a hidden folder in your home directory to save your Bash scripts. 

```bash
$ mkdir .tmux
```

Make two Bash scripts, one for the left side, one for the right.

```bash
$ touch ~/.tmux/right_status.sh
$ touch ~/.tmux/left_status.sh
```

The scripts are currently not executable ( rw-r--r-- ).

```bash
$ ls -lF ~/.tmux/*.sh
-rw-r--r-- 1 bw bw    0 Feb 19 18:44 /home/bw/.tmux/right_status.sh
-rw-r--r-- 1 bw bw    0 Feb 19 18:44 /home/bw/.tmux/left_status.sh
```

Make the scripts executable so they will run the chmod command.

```bash
$ chmod +x ~/.tmux/right_status.sh
$ chmod +x ~/.tmux/left_status.sh
```

The scripts are now executable ( rwxr-xr-x ).

```bash
$ ls -lF ~/.tmux/*.sh
-rwxr-xr-x 1 bw bw    0 Feb 19 18:44 /home/bw/.tmux/right_status.sh*
-rwxr-xr-x 1 bw bw    0 Feb 19 18:44 /home/bw/.tmux/left_status.sh*
```

# Status Bar Left Side

![tmux-status-left-side.png](https://i.postimg.cc/mrfZvrMJ/tmux-status-left-side.png)

First edit the left_status.sh script. Add the following content. The ip_address function displays the IP address and netmask.

`$ vim ~/.tmux/left_status.sh`

```bash
#!/bin/bash


function ip_address() {

    # Loop through the interfaces and check for the interface that is up.
    for file in /sys/class/net/*; do

        iface=$(basename $file);

        read status < $file/operstate;

        [ "$status" == "up" ] && ip addr show $iface | awk '/inet /{printf $2" "}'

    done

}
```

Underneath the IP address function add the CPU function. You must install lm-sensors for this to work. Run these two commands.

```bash
$ sudo apt install lm-sensors

$ sudo sensors-detect
```
Run the sensors command to see the output.

```bash
# Celcius

$ sensors

# Output
acpitz-acpi-0
Adapter: ACPI interface
temp1:        +27.8°C  (crit = +105.0°C)
temp2:        +29.8°C  (crit = +105.0°C)

# Fahrenheit

$ sensors -f

# Output
acpitz-acpi-0
Adapter: ACPI interface
temp1:        +82.0°F  (crit = +221.0°F)
temp2:        +85.6°F  (crit = +221.0°F)
```

Add the cpu_temperature function below the ip_address function.

```bash
function cpu_temperature() {

    # Display the temperature of CPU core 0 and core 1.
    sensors -f | awk '/Core 0/{printf $3" "}/Core 1/{printf $3" "}'

}
```

To see the memory usage we will add a memory_usage function. We need the bc command to calculate the percentage of memory used. 

Install bc command.

```bash
$ sudo apt install bc
```

Add the memory_usage function to the script.

```bash
function memory_usage() {

    if [ "$(which bc)" ]; then

        # Display used, total, and percentage of memory using the free command.
        read used total <<< $(free -m | awk '/Mem/{printf $2" "$3}')
        # Calculate the percentage of memory used with bc.
        percent=$(bc -l <<< "100 * $total / $used")
        # Feed the variables into awk and print the values with formating.
        awk -v u=$used -v t=$total -v p=$percent 'BEGIN {printf "%sMi/%sMi %.1f% ", t, u, p}'

    fi

}
```

The next function will display if the VPN is up by checking for the tun0 interface.

```bash
function vpn_connection() {

    # Check for tun0 interface.
    [ -d /sys/class/net/tun0 ] && printf "%s " 'VPN*'

}
```

To complete the left_status.sh script we will use a main function to call the other functions.

```bash
function main() {

    # Comment out any function you do not need. 
    ip_address
    cpu_temperature
    memory_usage
    vpn_connection

}

# Calling the main function which will call the other functions.
main
```

# Status Bar Right Side

![tmux-status-right-side.png](https://i.postimg.cc/qMNkgKxW/tmux-status-right-side.png)

Now let’s configure the right side.

`$ vim ~/.tmux/right_status.sh`

The battery meter function displays the level of the battery and changes color depending on the battery level. 
We need the acpi program for this. 

```bash
$ apt install acpi
```
Run acpi to see the output.

```bash
$ acpi

# Output
Battery 0: Unknown, 96%
```

If your terminal supports [emojis](https://unicode-table.com/en/emoji/) you can add an emoji to the status bar.

I will add the lighting bolt emoji to show when the battery is charging.

![emoji-icon.png](https://i.postimg.cc/vBXvJnnS/emoji-icon.png)

Add the battery_meter function to the Bash script. 

`$ vim ~/.tmux/right_status.sh`

```bash
#!/bin/bash

function battery_meter() {

    if [ "$(which acpi)" ]; then

        # Set the default color to the local variable fgdefault.
        local fgdefault='#[default]'

        if [ "$(cat /sys/class/power_supply/AC/online)" == 1 ] ; then

            local icon='🗲'
            local charging='+' 

        else
            
            local icon=''
            local charging='-'

        fi

        # Check for existence of a battery.
        if [ -x /sys/class/power_supply/BAT0 ] ; then

            batt0=$(acpi -b 2> /dev/null | awk '/Battery 0/{print $4}' | cut -d, -f1)

            case $batt0 in

                # From 100% to 75% display color grey.
                100%|9[0-9]%|8[0-9]%|7[5-9]%) fgcolor='#[fg=brightgrey]' 
                    ;;

                # From 74% to 50% display color green.
                7[0-4]%|6[0-9]%|5[0-9]%) fgcolor='#[fg=brightgreen]' 
                    ;;

                # From 49% to 25% display color yellow.
                4[0-9]%|3[0-9]%|2[5-9]%) fgcolor='#[fg=brightyellow]' 
                    ;;

                # From 24% to 0% display color red.
                2[0-4]%|1[0-9]%|[0-9]%) fgcolor='#[fg=brightred]'
                    ;;
            esac

            # Display the percentage of charge the battery has.
            printf "%s " "${fgcolor}${icon}${charging}${batt0}%${fgdefault}"

        fi
    fi
}
```

The next function will add to the script is to get the load average using the uptime command.

```bash
function load_average() {

    printf "%s " "$(uptime | awk -F: '{printf $NF}' | tr -d ',')"

}
```

To see the time, date, and timezone add the date_time function to the Bash script.

```bash
function date_time() {

    printf "%s " "$(date +'%Y-%m-%d %H:%M:%S %Z')"

}
```

The last function is the main function which calls the other functions.

```bash
function main() {

    battery_meter
    load_average
    date_time

}

# Calling the main function which will call the other functions.
main
```

# Complete Scripts

`$ cat ~/.tmux/left_status.sh`


```bash
#!/bin/bash


function ip_address() {

    # Loop through the interfaces and check for the interface that is up.
    for file in /sys/class/net/*; do

        iface=$(basename $file);

        read status < $file/operstate;

        [ "$status" == "up" ] && ip addr show $iface | awk '/inet /{printf $2" "}'

    done

}

function cpu_temperature() {

    # Display the temperature of CPU core 0 and core 1.
    sensors -f | awk '/Core 0/{printf $3" "}/Core 1/{printf $3" "}'

}

function memory_usage() {

    if [ "$(which bc)" ]; then

        # Display used, total, and percentage of memory using the free command.
        read used total <<< $(free -m | awk '/Mem/{printf $2" "$3}')
        # Calculate the percentage of memory used with bc.
        percent=$(bc -l <<< "100 * $total / $used")
        # Feed the variables into awk and print the values with formating.
        awk -v u=$used -v t=$total -v p=$percent 'BEGIN {printf "%sMi/%sMi %.1f% ", t, u, p}'

    fi

}

function vpn_connection() {

    # Check for tun0 interface.
    [ -d /sys/class/net/tun0 ] && printf "%s " 'VPN*'

}

function main() {

    # Comment out any function you do not need. 
    ip_address
    cpu_temperature
    memory_usage
    vpn_connection

}

# Calling the main function which will call the other functions.
main
```

`$ cat ~/.tmux/right_status.sh`

```bash

#!/bin/bash


function battery_meter() {

    if [ "$(which acpi)" ]; then

        # Set the default color to the local variable fgdefault.
        local fgdefault='#[default]'

        if [ "$(cat /sys/class/power_supply/AC/online)" == 1 ] ; then
            
            local icon='🗲'
            local charging='+' 

        else
            
            local icon=''
            local charging='-'
        fi

        # Check for existence of a battery.
        if [ -x /sys/class/power_supply/BAT0 ] ; then

            local batt0=$(acpi -b 2> /dev/null | awk '/Battery 0/{print $4}' | cut -d, -f1)

            case $batt0 in

                # From 100% to 75% display color grey.
                100%|9[0-9]%|8[0-9]%|7[5-9]%) fgcolor='#[fg=brightgrey]' 
                    ;;

                # From 74% to 50% display color green.
                7[0-4]%|6[0-9]%|5[0-9]%) fgcolor='#[fg=brightgreen]' 
                    ;;

                # From 49% to 25% display color yellow.
                4[0-9]%|3[0-9]%|2[5-9]%) fgcolor='#[fg=brightyellow]' 
                    ;;

                # From 24% to 0% display color red.
                2[0-4]%|1[0-9]%|[0-9]%) fgcolor='#[fg=brightred]'
                    ;;
            esac

            # Display the percentage of charge the battery has.
            printf "%s " "${fgcolor}${charging}${batt0}%${fgdefault}"

        fi
    fi
}

function load_average() {

    printf "%s " "$(uptime | awk -F: '{printf $NF}' | tr -d ',')"

}

function date_time() {

    printf "%s" "$(date +'%Y-%m-%d %H:%M:%S %Z')"

}

function main() {

    battery_meter
    load_average
    date_time

}

# Calling the main function which will call the other functions.
main
```

# Conclusion

You can now easily have a Bash script display useful information on the Tmux status bar. I hope you enjoyed reading this article.

Follow me on [Dev.to](https://dev.to/brandonwallace) and [Github](https://github.com/brandon-wallace).

Feel free to leave comment, questions, and suggestions.