#!/bin/bash # Configurable variables SEP=' | ' CPU_ON=1 CPU_SYM= MEM_ON=1 MEM_SYM= BL_ON=1 BL_SYM= VOL_ON=1 VOL_SYM_LOW= VOL_SYM_HI= VOL_SYM_MUTE= BAT_ON=1 BAT_SYM= BAT_SYM_PLG= BAT_SYM_UNK= BAT_CNT=1 DT_ON=1 DT_SYM='' DT_FMT='%a %d %I:%M%p' status_cpu() { ps --no-headers -eo %cpu | awk '{cpu = cpu + $1} END {print cpu}' } status_mem() { printf '%.0f%%' "$(free | awk 'NR == 2 {print $3 * 100 / $2}')" } status_bl () { local bl local max_bl printf -v bl '%s' \ "$(find /sys/class/backlight/*/brightness | head -n 1 | xargs cat)" printf -v max_bl '%s' \ "$(find /sys/class/backlight/*/max_brightness | head -n 1 | xargs cat)" # Multiply by 10^3 inside the arithemetic expansion so the integer arithmetic # will preserve 3 digits after the decimal point. Applying e-3 would provide # 3 decimal points for printf, but since we want the result scaled by 100, we # only apply e-1. printf will round the result to the specified presion. printf '%.0f%%' "$((bl * 1000 / max_bl))e-1" } status_vol () { printf '%s%%' \ "$(amixer get Master | tail -n 1 | sed -E 's/.*\[(.*)%\].*/\1/')" } status_vol_state() { local -r vol="${1:-0}" local state printf -v state '%s' \ "$(amixer get Master | tail -n 1 | sed -E 's/.*\[(.*)\]/\1/')" case "${state}" in on) if [[ "${vol}" -lt 50 ]]; then printf '%s' "${VOL_SYM_LOW}"; else printf '%s' "${VOL_SYM_HI}"; fi ;; *) printf '%s' "${VOL_SYM_MUTE}" ;; esac } status_bat_cap () { printf '%s' "$(find /sys/class/power_supply/BAT?/capacity \ | head -n "${BAT_CNT}" | xargs cat | tr '\n' '% ' | sed 's/ *$//')" } status_bat_state() { local state printf -v state '%s' \ "$(find /sys/class/power_supply/BAT?/status | head -n 1 | xargs cat)" case "${state}" in Discharging) printf '%s' "${BAT_SYM}" ;; Charging|Full) printf '%s' "${BAT_SYM_PLG}" ;; *) printf '%s' "${BAT_SYM_UNK}" ;; esac } status_dt () { printf '%s' "$(date +"${DT_FMT}")" } add_stat () { local -r val="$1" local -r sym="$2" local sep # Skip the separator for the first status section if [[ -n "${status}" ]]; then sep="${SEP}"; fi # Only output the status section if it has a value if [[ -n "${val}" ]]; then if [[ -n "${sym}" ]]; then status="${status}${sep}${sym} ${val}"; else status="${status}${sep}${val}"; fi fi } while :; do status='' if [[ "${CPU_ON}" -ne 0 ]]; then add_stat "$(status_cpu)" "${CPU_SYM}" fi if [[ "${MEM_ON}" -ne 0 ]]; then add_stat "$(status_mem)" "${MEM_SYM}" fi if [[ "${BL_ON}" -ne 0 ]]; then add_stat "$(status_bl)" "${BL_SYM}" fi if [[ "${VOL_ON}" -ne 0 ]]; then vol="$(status_vol)" add_stat "${vol}" "$(status_vol_state "${vol:0:-1}")" fi if [[ "${BAT_ON}" -ne 0 ]]; then add_stat "$(status_bat_cap)" "$(status_bat_state)" fi if [[ "${DT_ON}" -ne 0 ]]; then add_stat "$(status_dt)" "${DT_SYM}" fi xsetroot -name " ${status} " # Sleep until the beginning of the next minute, this way when we are showing # the time, the status updates on the minute ## sleep $((60 - $(date +%S))) sleep 2 done