монітор процесора на іскрах, ще раз

| щоденник, linux, bash

знову грався зі статусним рядком screen, і пригадав про генератор простописів (sparklines). накидав простий скрипт bash для видачі історії навантаження процесора заданої довжини:

> history.cpu
20 19 19 19 33

як працює? бере середнє навантаження процесора (насправді не зовсім, rtfm) за хвилину (перше значення з /proc/loadavg), форматує в цілі числа і додає в тимчасовий файл (/tmp/.history.cpu), пильнуючи, щоби низка значень у файлі мала задану довжину.

навіщо? можна згодовувати sparklines і отримувати простопис для прикрашання якоїсь панельки, або додавати до watch тощо:

> history.cpu | sparklines
███▁▁

код

#!/usr/bin/env bash
# tivasyk <tivasyk@gmail.com>
# A very simple CPU load history collector
# Example output:
# 12 23 14 45 98

# History file dir/name
HIST_DIR="/tmp"
HIST_FILE=".history.cpu"

# Defaults 
HIST_LEN=5      # History length = 5
HIST_SEP=" "    # Values separator = space (sparklines works fine with spaces and commas)
HIST_DEF=0      # Zero value = 0

# Check if history file exists, import if it does
if [ -a "${HIST_DIR}/${HIST_FILE}" ]; then
	# Found history file, read the first line and discard the rest
	HIST_LINE=$(cat "${HIST_DIR}/${HIST_FILE}")
else
	# Empty history, fill with defaults
	for ((i=1; i<=$HIST_LEN; i++)); do
		HIST_LINE="${HIST_LINE}${HIST_DEF}${HIST_SEP}"
	done
fi

# Add new CPU load reading to the right of the history
# Convert to integer in 0..100 range (important for sparklines)
# 0.01 -> 1, 0.19 -> 19, 1.01 -> 101
LOAD_CPU="$(cut -d' ' -f1 /proc/loadavg)"
LOAD_CPU="${LOAD_CPU/.}"
LOAD_CPU=$(( 10#${LOAD_CPU} ))
HIST_LINE="${HIST_LINE}${HIST_SEP}${LOAD_CPU}"

# Check the history length against the setting
HIST_ARRAY=( ${HIST_LINE} )
if [[ ${#HIST_ARRAY[@]} -gt ${HIST_LEN} ]]; then
	# Remove the leftmost (oldest) history entries 
	while [[ ${#HIST_ARRAY[@]} -gt ${HIST_LEN} ]]; do
		HIST_LINE="${HIST_LINE#* }"
		HIST_ARRAY=( ${HIST_LINE} )
	done
elif [[ ${#HIST_ARRAY[@]} -lt ${HIST_LEN} ]]; then
    # Add defaults to the left to fill the history
    while [[ ${#HIST_ARRAY[@]} -lt ${HIST_LEN} ]]; do
		HIST_LINE="${HIST_DEF}${HIST_SEP}${HIST_LINE}"
		HIST_ARRAY=( ${HIST_LINE} )
	done
fi

# Save the new history line back to the file
printf "${HIST_LINE}" > "${HIST_DIR}/${HIST_FILE}"

# Finally, print and exit
printf "${HIST_LINE}"