Make Your Tmux Status Line 100% Better With Bash
Tags: bash, linux, beginners, tutorial
Published: 2022-12-12 03:35:28


Did you know that you can easily use Bash to display information on the Tmux status line? Because of that the possibilities of what you can do are almost endless. You can display all sorts of useful information such as:

* Hostname
* IP address
* Netmask
* Gateway
* Memory
* CPU temperature
* System load
* Battery meter
* VPN status
* Time
* Date
* Weather report
* Git status

In this article I will show you an easy way to add information to your Tmux status line. 

## Requirements

* lm-sensors


Here is the default status line.

![status-line-original.png](https://i.postimg.cc/ncJJt73j/status-line-original.png)

Here is the status line enhanced to show more information.

![tmux-status-line-enhanced.png](https://i.postimg.cc/BvXWCCny/tmux-status-line-enhanced.png)

```bash
# Debian/Ubuntu based distributions
$ sudo apt install tmux


# Redhat/Fedora based distributions
$ sudo dnf install tmux
```

Check your Tmux version. Currently I am using version 3.3a.

```bash
$ tmux -V

# Output
tmux 3.3a
```

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

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

I will start out with a basic `.tmux.conf` configuration. Edit `.tmux.conf` and add the following lines. 

```bash

# .tmux.conf

bind r source-file ~/.tmux.conf \; display-message "RELOADING CONFIGURATION FILE…"

# STATUS LINE
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

# LEFT STATUS
set -g status-left-length 100
set -g status-left-style default
set -g status-left " "

# RIGHT STATUS
set -g status-right-length 100
set -g status-right-style default
set -g status-right " "

```

## Status Line Left Side

Tmux has same built in variables that you can use to display information such as `#h` to display the hostname. View the man page for more information.

```

$ man tmux

```

Add `#h` in between the double quotes

```

set -g status-left "#h"

```

You need to reload Tmux to see the changes. To reload Tmux you can type `exit` then launch Tmux again or you can reload Tmux by press the `CTRL+b` then `r`.
After reloading Tmux you will see the hostname of your computer on the status line.

![tmux-status-line-hostname-bw.png](https://i.postimg.cc/kgGhrgPR/tmux-status-line-hostname-bw.png)

## Adding the IP address and netmask to Status Line

All we need to do to customize the status line is to add Bash one-liners. To add Bash commands to the command line you only need to place each command inside a hash mark and parenthesis `#( <my-command> )`. 

I use this Bash command to get the IP address of the `enp4s0` Ethernet interface. 

```

$ ip addr | grep -e 'state UP' -A 2 | awk '/inet /{printf $2}'

# Output

192.168.0.101/26

```

I can add the command to the Tmux status line by placing it in between the parenthesis like this.

```

set -g status-left "#h #(ip addr | grep -e 'state UP' -A 2 | awk '/inet /{printf $2}')"

```

![tmux-status-line-ip-netmask-bw.png](https://i.postimg.cc/hPP2xtjZ/tmux-status-line-ip-netmask-bw.png)


## Adding the CPU Temperature to Status Line

Next I want to add the CPU temperature. To make that work you must use `lm-sensors`. Install `lm-sensors`.

```bash

# Debian/Ubuntu based distributions
$ sudo apt install lm-sensors


# Redhat/Fedora based distributions
$ sudo dnf install lm_sensors

```

Enable lm-sensors with this command and follow the prompts.

```bash
$ sudo sensors-detect
```
Run the `sensors` command to see the output. From the output you will need to figure out which line displays information about the CPU. The line you need might be labeled `Tccd1` or `CPU`. Add the `-f` argument to the sensors command to see the temperature in Fahrenheit.


```bash

$ sensors -f

# Partial Output 

intel-isa-0000
Adapter: ISA adapter
fan1:           0 RPM
CPU:          +96.8°F  
GPU:              N/A  
temp3:        +96.8°F  
temp4:        +32.0°F  
temp5:        +96.8°F  
temp6:        +96.8°F  
temp7:        +96.8°F  
temp8:            N/A  

intel-pci-0400
Adapter: PCI adapter
vddgfx:      794.00 mV 
vddnb:       604.00 mV 
edge:         +95.0°F  
PPT:           3.16 W  

BAT0-acpi-0
Adapter: ACPI interface
in0:          17.27 V  
[....]

```

Add this code `#(sensors -f | awk '/CPU/{printf $2}')` to the end of the left status line. This command uses awk to find the row with the text `CPU` and print the second column.

```bash

set -g status-left "#h #(ip addr show enp4s0 | awk '/inet /{printf $2}') #(sensors -f | awk '/CPU/{printf $2}')"

``` 

![tmux-status-line-cpu-temp-bw.png](https://i.postimg.cc/pVkZ2MZf/tmux-status-line-cpu-temp-bw.png)


## Adding Memory to the Status Line

Next, I want to view the amount of memory used, the total memory, and calculate the percentage of memory in use. To do that I use the `free` command.

```bash

# Amount of memory used / total amount of memory
$ free -m -h | awk '/Mem/{printf $3"/"$2}'

# Output

3.3Gi/62Gi

# Calculate percentage of memory used

$ free -m | awk '/Mem/{printf "%.2f%", 100*$3/$2}'

# Output

2.1%

```

Careful here! To get the memory command to display properly in the Tmux status line requires that certain characters be escaped.
Here I am using the backward slash `\` to escape the double quote `\"`, the period `\.`, the percent sign `\%`, and the forward slash `\/`.

Before escaping characters:

```bash

#(free -m -h | awk '/Mem/{printf $3"/"$2}') #(free -m | awk '/Mem{printf "%.2f%", 100*$2/$3}')"

```

After escaping characters:

```bash

#(free -m -h | awk '/Mem/{printf $3\"\/\"$2}') #(free -m | awk '/Mem{printf \"\%\.2f\%\", 100*$2/$3}')"

```

The status left should now look like this.

```bash

set -g status-left "#h #(ip addr | grep -e 'state UP' -A 2 | awk '/inet /{printf $2}') #(sensors | awk '/CPU/{printf $2}') #(free -m -h | awk '/Mem/{printf $3\"\/\"$2}') #(free -m | awk '/Mem{printf \"\%\.2f\%\", 100*$2/$3}')"

``` 

![tmux-status-line-memory-bw.png](https://i.postimg.cc/mkr7chwQ/tmux-status-line-memory-bw.png)


## Adding the Battery Level to Status Line

I want to see the battery level and see if it is charging on not. To do that I can check the `/sys` file system for the battery information. 

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

I will test to see if the power cable is plugged in and show a lighting bolt icon if it is. I will show the percentage of battery remaining next to the lightning bolt.

If `$(cat /sys/class/power_supply/AC/online)` is equal to `1` the lightning bolt will display. 

Add these lines to the end of the left status line. 

```bash

#([ $(cat /sys/class/power_supply/AC/online) == 1 ] && printf %s'🗲') 

#( $(cat /sys/class/power_supply/BAT0/capacity)\% )

```

The left status line should look something like this.


```bash

set -g status-left "#h #(ip addr | grep -e 'state UP' -A 2 | awk '/inet /{printf $2}') #(sensors | awk '/CPU/{printf $2}') #(free -m -h | awk '/Mem/{printf \$3\"\/\"\$2\}') #(free -m | awk '/Mem{printf 100*$2/$3" %"}') #([ $(cat /sys/class/power_supply/AC/online) == 1 ] && printf %s'🗲') #(cat /sys/class/power_supply/BAT0/capacity)\%"

``` 

![tmux-status-line-battery-bw.png](https://i.postimg.cc/nLksvpMT/tmux-status-line-battery-bw.png)


## Adding the VPN to Status Line

I want to check if the VPN is up and see the IP address assigned to it. Depending on the VPN you use you might have to check the tun0 or ppp0 interface.

```bash

ip a | egrep 'ppp0|tun0' -A 2 | awk '/inet /{printf $2}'

# Output

10.20.3.45

```

Add this to the end of the left status line.

```bash

#([ ! -z $(ip a | egrep 'ppp0|tun0' -A 2 | awk '/inet /{printf $2}') ] && echo $(ip a | egrep 'ppp0|tun0' -A 2 | awk '/inet /{printf \"VPN \"$2}'))

```

My status line now looks like this.

```bash

set -g status-left "#h #(ip addr | grep -e 'state UP' -A 2 | awk '/inet /{printf $2}') #(sensors | awk '/CPU/{printf $2}') #(free -m -h | awk '/Mem/{printf \$3\"\/\"\$2\}') #(free -m | awk '/Mem{printf 100*$2/$3" %"}') #([ $(cat /sys/class/power_supply/AC/online) == 1 ] && printf %s'🗲') #(cat /sys/class/power_supply/BAT0/capacity)\% #([ ! -z $(ip a | egrep 'ppp0|tun0' -A 2 | awk '/inet /{printf $2}') ] && echo $(ip a | egrep 'ppp0|tun0' -A 2 | awk '/inet /{printf \"VPN \"$2}'))"

``` 

![tmux-status-line-enhanced-bw.png](https://i.postimg.cc/NMF0mX3f/tmux-status-line-enhanced-bw.png)


# Status Bar Right Side

Now let’s configure the right side.


I will get the load average using the `uptime` command.

```bash

$ uptime

# Output

02:39:38 up 12:18,  1 user,  load average: 0.20, 0.11, 0.10

```

The number of columns in the output can change so depending on the time. To get around that problem I use $(NF) to get the last column and `tr` to remove the colon characters.

Add this to the right status line option with escaped characters in between the double quotes.

```bash

set -g status-right "#(uptime | awk '{printf \$(NF-2)\" \"\$(NF-1)\" \"\$(NF)}' | tr -d ',')"

```

The last thing I will add is the date, time, and timezone using variables to status-right. Tmux uses strftime formatting to display variables. Given that, I can view the date and time using a custom format. Example: `%F` represents `YYYY-mm-dd`  `%T` represents `HH:MM:SS` . See the man page for more information `man strftime`.



Add that to the end of the right status line.

```bash

set -g status-right "#(uptime | awk '{printf \$(NF-2)\" \"\$(NF-1)\" \"\$(NF)}' | tr -d ',') %F %T %Z"

```

# Adding a Bash Script

If you needed to configure more complicated code than what could fit on one line you can make a separate Bash file and add it like this.

```bash

set -g status-right "#( example.sh )"

```

```bash

$ cat example.sh

#!/bin/bash
# example.sh

# Get the IP address dynamically
function get_ip_address() {
    mapfile -t iface_arr < <(echo $(ls /sys/class/net/))
    for iface in $iface_arr; do 
        if [ "$(cat /sys/class/net/$iface/operstate)" == "up" ]; then
            printf "    %s\n" "${iface^^}: $(ip addr show $iface | awk '/inet /{printf $2}')"; 
        fi
    done
}

get_ip_address

```

# Adding Color

Run this code in your terminal to see what colors you have available.

```bash

#!/bin/bash

for num in {0..255}; do  
    printf "%s\033[38;5;${num}mcolour${num}\033[0m \t"; 
    
    if [ $(expr $((num+1)) % 8) -eq 0 ]; then
        printf "\n"
    fi
done

```

![tmux-colour-chart.png](https://i.postimg.cc/ncBh4pP7/tmux-colour-chart.png)


Now you can add color to your status line. Add foreground colors by setting a `#[fg=<colourN>]` or `#[bg=<colourN>]` variable to the color of your choice.
`fg=` is for the foreground color `bg=` is to set the background color in between square brackets. Use `#[default]` to back to the default colors.


```bash

set -g status-left "#[fg=colour220] #h #[fg=colour47] #(ip addr | grep -e 'state UP' -A 2 | awk '/inet /{printf $2}') #[colour27] #(sensors -f | awk '/CPU/{printf $2}') #[default]"

```

![tmux-status-line-color.png](https://i.postimg.cc/WpygXGwZ/tmux-status-line-color.png)


The status lines can get quite long. If you do not like long lines use the backslash to break it up.

```bash

set -g status-left "#[fg=colour220]#h\
#[fg=colour196] #(ip addr | grep -e 'state UP' -A 2 | awk '/inet /{printf $2}')\
#[fg=colour39] #(sensors | awk '/CPU/{printf $2}')\
#[fg=colour40] #(free -m -h | awk '/Mem/{printf \$3\"\/\"\$2\}')\
#[fg=colour128] #(free -m | awk '/Mem{printf 100*$2/$3" %"}')\
#[fg=colour202] #([ $(cat /sys/class/power_supply/AC/online) == 1 ] && printf %s'🗲') #(cat /sys/class/power_supply/BAT0/capacity)\%\
#[fg=colour7] #([ ! -z $(ip a | egrep 'ppp0|tun0' -A 2 | awk '/inet /{printf $2}') ] && echo $(ip a | egrep 'ppp0|tun0' -A 2 | awk '/inet /{printf \"VPN \"$2}'))\
#[default]"

``` 

# Complete Status Line Configuration

```bash

# .tmux.conf

bind r source-file ~/.tmux.conf \; display-message "RELOADING CONFIGURATION FILE…"

# STATUS LINE
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

# LEFT STATUS
set -g status-left-length 100
set -g status-left-style default
set -g status-left "#[fg=colour220]#h\
#[fg=colour196] #(ip addr | grep -e 'state UP' -A 2 | awk '/inet /{printf $2}')\
#[fg=colour39] #(sensors | awk '/CPU/{printf $2}')\
#[fg=colour40] #(free -m -h | awk '/Mem/{printf \$3\"\/\"\$2\}')\
#[fg=colour128] #(free -m | awk '/Mem{printf 100*$2/$3" %"}')\
#[fg=colour202] #([ $(cat /sys/class/power_supply/AC/online) == 1 ] && printf %s'🗲') #(cat /sys/class/power_supply/BAT0/capacity)\%\
#[fg=colour7] #([ ! -z $(ip a | egrep 'ppp0|tun0' -A 2 | awk '/inet /{printf $2}') ] && echo $(ip a | egrep 'ppp0|tun0' -A 2 | awk '/inet /{printf \"VPN \"$2}'))\
#[default]"

# RIGHT STATUS
set -g status-right-length 100
set -g status-right-style default
set -g status-right "#[fg=colour39] #(uptime | awk '{printf \$(NF-2)\" \"\$(NF-1)\" \"\$(NF)}' | tr -d ',')\
#[fg=colour40] %F\
#[fg=colour128] %T\
#[fg=colour202] %Z\
#[default]"

```

# Conclusion

You can now easily have a Bash display useful information on the Tmux status line. I hope you learned something new and enjoyed reading this article.

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

Feel free to leave comments, questions, and suggestions.