Skip to content

Instantly share code, notes, and snippets.

@gatopeich
Last active May 13, 2026 08:24
Show Gist options
  • Select an option

  • Save gatopeich/567c04d523833c40c7cca0ab06baa736 to your computer and use it in GitHub Desktop.

Select an option

Save gatopeich/567c04d523833c40c7cca0ab06baa736 to your computer and use it in GitHub Desktop.
TMUX/Byobu status bar: CPU+MEM usage bars in only 4 chars
#!/usr/bin/env python3
# Byobu custom status script: CPU + MEM as colored UTF-8 block chars.
# Install: place in ~/.byobu/bin/01_cpu_mem_bars and chmod +x
# Enable: add 'custom' to tmux_right in ~/.byobu/status
#
# Integration — vanilla tmux (~/.tmux.conf):
# set -g status-right '#(~/.byobu/bin/01_cpu_mem_bars)%H:%M:%S'
#
# Integration — byobu (~/.byobu/profile.tmux):
# source $BYOBU_PREFIX/share/byobu/profiles/tmux
# set -g status-right '#(byobu-status tmux_right)#(~/.byobu/bin/01_cpu_mem_bars)%H:%M:%S'
#
# Output examples (as seen in byobu status bar):
# c▁m▂ CPU ~10% (cyan), MEM ~20% (cyan) — all quiet
# c▃M▆ CPU ~25% (cyan), MEM ~70% (yellow) — memory notable
# C▅M▇ CPU ~60% (yellow), MEM ~85% (red) — both busy
# C█M█ CPU ~95% (red), MEM ~95% (red) — under pressure
# C▆M! MEM ≥95% — memory alarm: M! in white bold on red background
#
# Letter is uppercase when usage > 50%, lowercase otherwise.
# Colors: cyan <30%, green 30-60%, yellow 60-85%, red >85%
import os, time
CACHE = os.path.join(os.environ.get('TMPDIR', '/tmp'), 'proc_stat.last')
def cpu_pct():
cur = [int(x) for x in open('/proc/stat').readline().split()[1:]]
try:
prev = [int(x) for x in open(CACHE).read().split()]
cached_time = os.path.getmtime(CACHE)
except OSError:
cached_time, prev = 0, cur
total = sum(cur) - sum(prev)
# Write cache only when stale or on counter wrap — avoids redundant writes
# when multiple byobu status processes run close together each second.
# time.time() is called here, as close as reasonable to cache write.
if time.time() - cached_time > 1 or total <= 0:
with open(CACHE, 'w', encoding="utf-8") as cache:
cache.write(' '.join(map(str, cur)))
if total <= 0:
return 0
idle = (cur[3] + cur[4]) - (prev[3] + prev[4])
return (total - idle) * 100 // total
def mem_pct():
info = {}
for line in open('/proc/meminfo'):
k, v = line.split()[0].rstrip(':'), int(line.split()[1])
info[k] = v
if 'MemTotal' in info and 'MemAvailable' in info: break
return (info['MemTotal'] - info['MemAvailable']) * 100 // info['MemTotal']
def fmt(pct):
color = 'red' if pct > 85 else 'yellow' if pct > 60 else 'green' if pct > 30 else 'cyan'
bar = chr(0x2580 + max(1, pct * 8 // 100))
return color, bar
cpu = cpu_pct()
mem = mem_pct()
cc, cb = fmt(cpu)
cl = 'C' if cpu > 50 else 'c'
if mem >= 95:
mem_part = '#[bg=red,fg=white,bold]M!'
else:
mc, mb = fmt(mem)
ml = 'M' if mem > 50 else 'm'
mem_part = f'#[fg={mc}]{ml}{mb}'
print(f'\033#[fg=black,bg=default]▐#[fg={cc},bg=black]{cl}{cb}{mem_part}#[fg=black,bg=default]▌#[default]', end='')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment