Last active
June 1, 2024 12:05
-
-
Save tkapias/d66d86fe5c3c7df1470288b27559e296 to your computer and use it in GitHub Desktop.
lservices - colorized and searchable table of all SystemD units & unit-files - extracted functions from my .bashrc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# executed by bash(1) for non-login shells. | |
# ============================== | |
# FUNCTIONS | |
# ============================== | |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
# Output a table with header | |
# uses skim for fuzzy and preview, or default to less or cat. | |
# skim can use tmux if present. | |
# from skim 'f1' will cat unit config and status to terminal. | |
outputviewer() { | |
if command -v sk-tmux 1> /dev/null; then | |
$3 sk-tmux -d 75% --case=smart --no-sort --layout=reverse-list --exit-0 --color=dark,bg+:237 --no-mouse --cycle --multi --ansi --tabstop=2 --header-lines=1 \ | |
--prompt="$1" \ | |
--preview-window="right:45%:wrap" \ | |
--bind="ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all,ctrl-p:toggle-preview,f1:execute-silent:($4; $2; echo)" \ | |
--preview="echo -e \"\\\e[1;37mKEYS: \\\e[1;33m\\\e[1;36menter/esc \\\e[1;33m\\\e[1;36mtab \\\e[1;33m\\\e[1;36mctrl-c \\\e[1;33m\\\e[1;36mctrl-a \\\e[1;33m\\\e[1;36mctrl-d \\\e[1;33m/\\\e[1;36mctrl-t \\\e[1;33m\\\e[1;36mctrl-p\\\n\\\e[1;37mPREVIEW: \\\e[0m\\\n\"; $2" | |
elif command -v less 1> /dev/null; then | |
less --no-lessopen --use-color --quit-if-one-screen --ignore-case --LONG-PROMPT --RAW-CONTROL-CHARS --QUIET --no-init --chop-long-lines --tilde --mouse --header 1 --prompt "$1" | |
else | |
cat | |
fi | |
} | |
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
# colorized and searchable table of all SystemD units & unit-files | |
# per type,user or system, with a header and a preview. | |
lservices() { | |
Help() { | |
cat <<- HEREDOC | |
List Systemd units or c-groups. | |
Simplified and colorful, optional preview and fuzzy search with skim. | |
Syntax: lservices [-h] [-c] [-p] [-a|-d|m|P|s|S|t|T] [<username>] | |
Output: ServiceName UID STATE DESCRIPTION | |
options: | |
-h Print this Help. | |
-c Display Systemd c-groups list with systemd-cgls. | |
-p Disable the pager feature. | |
Change default listing (service,scopes,socket): | |
-a List service related units (service,scope,socket,target,timer,slice). | |
-d List devices. | |
-m List mounts and automounts. | |
-P List paths. | |
-s List slices. | |
-S List swaps. | |
-t List targets. | |
-T List timers. | |
<username> [root] display --system services, | |
[other] display --user services, | |
[empty] default to current user. | |
HEREDOC | |
} | |
local _LIST="service,scope,socket" | |
local _LISTGREP='\.service|\.scope|\.socket' | |
local OPTIND=0 | |
while getopts ":hcpadmPsStT" option; do | |
case $option in | |
h) Help; return 0 ;; | |
c) systemd-cgls -la | |
return 0 ;; | |
p) local _NOPAGER=1;; | |
a) local _LIST="service,scope,socket,target,timer,slice" | |
local _LISTGREP='\.service|\.scope|\.socket|\.target|\.timer|\.slice';; | |
d) local _LIST="device" | |
local _LISTGREP="\.$_LIST";; | |
m) local _LIST="mount,automount" | |
local _LISTGREP='\.mount|\.automount';; | |
P) local _LIST="path" | |
local _LISTGREP="\.$_LIST";; | |
s) local _LIST="slice" | |
local _LISTGREP="\.$_LIST";; | |
S) local _LIST="swap" | |
local _LISTGREP="\.$_LIST";; | |
t) local _LIST="target" | |
local _LISTGREP="\.$_LIST";; | |
T) local _LIST="timer" | |
local _LISTGREP="\.$_LIST";; | |
\?) echo -e "Unknown option: -$OPTARG \n" >&2; Help; return 1;; | |
: ) echo -e "Missing argument for -$OPTARG \n" >&2; Help; return 1;; | |
* ) echo -e "Unimplemented option: -$option \n" >&2; Help; return 1;; | |
esac | |
done | |
shift $((OPTIND-1)) | |
if [[ -z $1 ]]; then | |
local _UID=$(id -u) | |
else | |
local _UID=$(id -u $1) | |
fi | |
if [[ "$_UID" == "0" ]]; then | |
local _SYSTEMCTL="systemctl --system" | |
local _SUDO="sudo TMUX=$TMUX TMUX-PANE=$TMUX-PANE" | |
local _LOADED=$(sudo systemctl list-units --system -q --plain --full --no-pager -t "$_LIST" | grep -E "$_LISTGREP") | |
local _OTHER=$(sudo systemctl list-unit-files --system -q --plain --full --no-pager --state disabled,indirect -t "$_LIST" | grep -E "$_LISTGREP") | |
elif [[ "$_UID" == "$(id -u)" ]]; then | |
local _SYSTEMCTL="systemctl --user" | |
local _SUDO="" | |
local _LOADED=$(systemctl list-units --user -q --plain --full --no-pager -t "$_LIST" | grep -E "$_LISTGREP") | |
local _OTHER=$(systemctl list-unit-files --user -q --plain --full --no-pager --state disabled,indirect -t "$_LIST" | grep -E "$_LISTGREP") | |
else | |
local _SUDO="sudo TMUX=$TMUX TMUX-PANE=$TMUX-PANE" | |
local _SYSTEMCTL="machinectl -q shell --uid=$_UID .host /usr/bin/systemctl --user" | |
local _LOADED=$(sudo machinectl -q shell --uid="$_UID" .host /usr/bin/systemctl list-units --user -q --plain --full --no-pager -t "$_LIST" | grep -E "$_LISTGREP") | |
local _OTHER=$(sudo machinectl -q shell --uid="$_UID" .host /usr/bin/systemctl list-unit-files --user -q --plain --full --no-pager --state disabled,indirect -t "$_LIST" | grep -E "$_LISTGREP") | |
fi | |
local _LOADED=$(echo "$_LOADED" | awk ' \ | |
BEGIN { | |
red = "\033[1;31m" | |
green = "\033[1;32m" | |
yellow = "\033[1;33m" | |
blue = "\033[1;36m" | |
reset = "\033[0m" | |
map["running"] = green | |
map["start"] = green | |
map["listening"] = green | |
map["active"] = green | |
map["mounted"] = green | |
map["plugged"] = green | |
map["waiting"] = green | |
map["exited"] = yellow | |
map["stop"] = yellow | |
map["failed"] = red | |
map["dead"] = red | |
} | |
match($0,/^(.*)\.([a-z]+)\s*[a-z-]+\s*([a-z]+)\s([a-z]+)\s*(.*)$/,a) { | |
status = a[4] | |
if ( status in map ) | |
$0 = blue a[1] "\t" a[2] reset "\t" map[status] status reset "\t" a[5] | |
else | |
$0 = blue a[1] "\t" a[2] reset "\t" a[4] "\t" a[5] | |
} | |
{ print } ' | |
) | |
local _OTHER=$(echo "$_OTHER" | awk ' \ | |
BEGIN { | |
red = "\033[1;31m" | |
yellow = "\033[1;33m" | |
blue = "\033[1;36m" | |
reset = "\033[0m" | |
map["disabled"] = red | |
map["indirect"] = yellow | |
map["enabled"] = yellow | |
} | |
match($0,/^(.*)\.([a-z]+)(\s*)([a-z]+)\s*([a-z]+)$/,a) { | |
status = a[4] | |
preset = a[5] | |
$0 = blue a[1] "\t" a[2] reset "\t" map[status] status reset "\t(preset: " map[preset] preset reset ")" | |
} | |
{ print } ' | |
) | |
local _OUTPUT=$(printf "%s\n%s" "$_LOADED" "$_OTHER" | sort -f -u -t$'\t' -k 1,2) | |
printf "Unit\tType\tState\tComments\n%s" "$_OUTPUT" | column -s$'\t' -t | outputviewer "Systemd states for '$_LIST' as '$(id -u -n $_UID)' > " "SYSTEMD_URLIFY=0 SYSTEMD_COLORS=1 $_SYSTEMCTL -q --plain --full --no-pager --output=short status -- {1}.{2} | cat" "$_SUDO" "echo; SYSTEMD_URLIFY=0 SYSTEMD_COLORS=1 $_SYSTEMCTL -q --plain --full --no-pager --output=short cat -- {1}.{2} | cat; echo" | |
} |
Author
tkapias
commented
May 22, 2024
Edited Revision 8:
- Use Skim for fuzzy search and preview the status of the units.
- Added a static header for skim, less and cat.
- Added a generated prompt for skim and less.
Edited Revision 10:
- Skim bind 'f1' to silently print the unit config file and the status of the highlighted line to the terminal.
Edited Revision 16:
- More optional options for skim to disable h-scroll
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment