Skip to content

Instantly share code, notes, and snippets.

@adrolter
Last active February 5, 2021 07:58
Show Gist options
  • Save adrolter/f55958ad27de2c341a4dbc490978dd40 to your computer and use it in GitHub Desktop.
Save adrolter/f55958ad27de2c341a4dbc490978dd40 to your computer and use it in GitHub Desktop.
Qubes OS System Monitor for Lenovo ThinkPads
#!/usr/bin/sh
# qubes-sysmon.sh – Qubes OS System Monitor for Lenovo ThinkPads
# Copyright (c) 2017 Adrian Günter
#
# @Authors Adrian Günter <adrian|gntr/me>
# @URL https://gist.github.com/adrianguenter/f55958ad27de2c341a4dbc490978dd40
# @License http://opensource.org/licenses/MIT
# @Shells Bash >=4.4, Dash >=0.5
# @Usage [WATCHARGS=d] qubes-sysmon.sh <timeout-secs>
#
# $GLOBAL_VAR_NAME / $CONSTANT_NAME
# $local_var_name
# $CommandName
# FunctionName
#
# shellcheck disable=SC2016,SC2028
# Put Bash in POSIX mode (ignored for other shells)
POSIXLY_CORRECT=y
# Enable nounset and noclobber
set -uf
# Set a conservative umask
umask 0027
# No path searching
# shellcheck disable=SC2123
PATH=
readonly Cat='/usr/bin/cat'
readonly Echo='/usr/bin/echo'
readonly Journalctl='/usr/bin/journalctl'
readonly Perl='/usr/bin/perl'
readonly Printf='/usr/bin/printf'
readonly Sensors='/usr/bin/sensors'
readonly Tput='/usr/bin/tput'
readonly Xenpm='/usr/sbin/xenpm'
readonly Xentop='/usr/sbin/xentop'
readonly Wc='/usr/bin/wc'
readonly P="${Printf}"
readonly TOP_LEFT='┍━╸'
readonly TOP_RIGHT='━━╍┅┉┄┈'
readonly BOT_LEFT='└'
readonly BOT_RIGHT='╌┄┈'
readonly LINE_PREFIX='│'
readonly BOT_D_LEN=55
readonly BOT_D="${BOT_LEFT}$(perl -e'print "─" x '$BOT_D_LEN)${BOT_RIGHT}"
readonly ESC_BOLD=$($Tput bold)
readonly ESC_RESET='\033[0m'
readonly PERL_BEGIN='BEGIN {my @l = ()}'
readonly PERL_END='END {print join(" ╿ ",@l)}'
SectionHeader() {
local len; len=$($P '%s' "${1}" | $Wc --chars)
$Printf "${TOP_LEFT} ${ESC_BOLD}%s${ESC_RESET} %s${TOP_RIGHT}" "${1}" "$($Perl -e'print "━"x'$((BOT_D_LEN-(len+8))))"
}
JournalctlUnit() {
local perl='$. > '"$((${2}+1))"' && exit;'
perl="${perl}"'printf("'${LINE_PREFIX}' %s",$_=~s/^[A-z]+ \d+ \d+:\d+:\d+ \K.+\[(\d+)\]:/[$1]/r) unless $. == 1'
$Echo "$P '%s\n' '$(SectionHeader "${1}")';\
$Journalctl --no-pager -xr -b-0 -u'${1}' | $Perl -ne'${perl}';\
$P '%s\n' '${BOT_D}'"
}
ThermalSensors() {
local perl='BEGIN { my $tp = 0 }; $tp or /thinkpad-isa/ && { ($tp = 1) and next } or next;'
perl="${perl}"'/^(temp1|Core \d+):\s+([+-]?\d+\.\d+)C/ || next;'
perl="${perl}"'my $v = $2; push @l,sprintf("%s: %s",$1=~s/^Core /core/r,$v);'
$Echo "$P '%s\n${LINE_PREFIX} ' '$(SectionHeader "Thermal Sensors (C)")';\
$Sensors -A | $Perl -ne'${PERL_BEGIN}' -e'${perl}' -e'${PERL_END}';\
$P '\n%s\n' '${BOT_D}'"
}
ThinkFan() {
local perl='/^command/ && next; $_ =~ s/:\s+/: /; push @l,s/\n//r;'
$Echo "$P '%s\n${LINE_PREFIX} ' '$(SectionHeader "ThinkFan")';\
$Cat /proc/acpi/ibm/fan | $Perl -ne'${PERL_BEGIN}' -e'${perl}' -e'${PERL_END}';\
$P '\n%s\n' '${BOT_D}'"
}
XenCpufreq() {
local perl='BEGIN {my $c = -1}; /^current.+ (\d+) MHz$/ && push @l,sprintf("core%d: %s",$c++,$1);'
$Echo "$P '%s\n${LINE_PREFIX} ' '$(SectionHeader "CPU Core Frequency (MHz)")';\
$Xenpm get-cpufreq-states | $Perl -ne'${PERL_BEGIN}' -e'${perl}' -e'${PERL_END}';\
$P '\n%s\n' '${BOT_D}'"
}
Xentop() {
local perl='BEGIN { my $c = 0 }; $s = "", $e = ""; /^\s*NAME\s+STATE\s+/ and { $c++, $s = "'${ESC_BOLD}'", $e = "'${ESC_RESET}'" };'
perl="${perl}"'$c > 1 || next; printf "'${LINE_PREFIX}' $s%10s %-6s %8s %-6s %8s %-6s %s$e\n",$F[0],$F[1],$F[2],$F[3],$F[4],$F[5];'
$Echo "$P '%s\n' '$(SectionHeader "xentop")';\
$Xentop -b -d"${1}" -i2 | $Perl -lane'${perl}';\
$P '%s\n' '${BOT_D}'"
}
__main() {
local n=${1:-1}; $Watch -tc"${WATCHARGS:-}" -n0 -x "${SHELL}" -c "\
$P '%s [Interval: %d sec(s)]\n\n' \"\$(date)\" '${n}';\
$(XenCpufreq);\
$(ThinkFan);\
$(ThermalSensors);\
$(Xentop "${n}");\
$(JournalctlUnit "qubes-thinkpad-coolingd.service" 10);\
"
}
__main "${@}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment