DEV Community

minnogit
minnogit

Posted on • Edited on

Elenco in Conky di applicazioni con l'uso della swap

In continuazione del precedente post, adesso vediamo come stampare in Conky un elenco di programmi con la relativa quantità di swap usata.

Prepariamo uno script bash che restituisce il testo che vogliamo visualizzare in Conky basato sul comando spiegato in precedenza ma con una differenza in particolare: ci possono essere più processi in esecuzione dello spesso comando (ad esempio 5 processi per Chrome) ma quello che voglio visualizzare in Conky, è la somma della swap usata da tutti i processi dello stesso comando.

unioneTest=""
for file in /proc/*/status; do
  if [[ -f "$file" ]]; then
    test=$(awk '/^(Name:)/ {awk_name=$2} /^(VmSwap:)/ {awk_vmswap=$2" "$3} /^(Pid:)/ {awk_pid=$2} END { if (awk_vmswap && substr(awk_vmswap,1,1) != '0' ) print awk_name" "awk_pid" "awk_vmswap}' $file)
    if [ -n "$test" ]; then
      unioneTest+=$test"\n"
    fi
  fi
done
Enter fullscreen mode Exit fullscreen mode

A differenza del comando precedente, alla fine dell'analisi awk di ogni file, viene verificato se la variabile awk_vmswap non è vuota e se il primo carattere non è "0". Se queste condizioni sono soddisfatte, viene creato un nuovo record di informazioni sul processo, che viene memorizzato nella variabile test.
Se la variabile test non è vuota, viene aggiunto alla variabile unioneTest e viene inserito un carattere di nuova linea ("\n") per separare i record.
Alla fine, $unioneTest conterrà l'elenco dei processi che usano la swap.

Il passo successivo, è sommare tra loro i valori di swap degli stessi comandi.
Per farlo, creo un array associativo denominato somma mediante il comando declare -A.
Questo array verrà utilizzato per accumulare i valori della terza colonna (ovvero la quantità di swap usata) dei processi che hanno lo stesso nome.

dati=$unioneTest
declare -A somma

while read -r linea; do
  nome=$(echo "$linea" | cut -d ' ' -f1)
  valore=$(echo "$linea" | cut -d ' ' -f3)
  ((somma[$nome] += valore))
done <<<"$(echo -e "$unioneTest")"
Enter fullscreen mode Exit fullscreen mode

Il ciclo while viene alimentato con un here-string (<<<) che contiene l'output di un comando echo -e che converte una stringa contenente i dati da elaborare.

Infine, stampiamo l'elenco dall'array somma inserendo in ogni riga il numero di spazi necessario ad avere una lunghezza prestabilita. Gli spazi vengono inseriti tra il nome del comando e la quantità di swap usata.
La lunghezza delle righe, verrà specificata da un parametro dello script.

elenco=""
  for nome in "${!somma[@]}"; do
    tmp="$nome${somma[$nome]} kB\n"
    nrSpacesToAdd=$(expr $spaces - ${#tmp})
    elenco+="$nome$(printf '%*s' $nrSpacesToAdd)${somma[$nome]} kB\n"
  done
  echo -e "$elenco" | sort -k 2 -n -r
Enter fullscreen mode Exit fullscreen mode

nrSpacesToAdd calcola il numero di spazi da aggiungere ad una stringa, in modo da ottenere una stringa di una lunghezza specifica.
La variabile $spaces rappresenta il numero totale di spazi che si desidera avere nella stringa finale.
La variabile ${#tmp} rappresenta la lunghezza della stringa tmp.

(printf '%*s' $nrSpacesToAdd) viene utilizzato per generare una stringa di spazi della lunghezza $nrSpacesToAdd.

Questo è lo script completo:

#!/bin/bash

if [ $# -eq 0 ]; then
  echo "Specificare la lunghezza delle stringhe"
  exit 1
fi

# Lunghezza voluta delle stringhe
spaces=$1

unioneTest=""
for file in /proc/*/status; do
  if [[ -f "$file" ]]; then
    test=$(awk '/^(Name:)/ {awk_name=$2} /^(VmSwap:)/ {awk_vmswap=$2" "$3} /^(Pid:)/ {awk_pid=$2} END { if (awk_vmswap && substr(awk_vmswap,1,1) != '0' ) print awk_name" "awk_pid" "awk_vmswap}' $file)
    if [ -n "$test" ]; then
      unioneTest+=$test"\n"
    fi
  fi
done

if [ -n "$unioneTest" ]; then
  dati=$unioneTest
  declare -A somma

  while read -r linea; do
    nome=$(echo "$linea" | cut -d ' ' -f1)
    valore=$(echo "$linea" | cut -d ' ' -f3)
    ((somma[$nome] += valore))
  done <<<"$(echo -e "$unioneTest")"

  elenco=""
  for nome in "${!somma[@]}"; do
    tmp=" $nome${somma[$nome]} kB\n"
    nrSpacesToAdd=$(expr $spaces - ${#tmp})
    elenco+="$nome$(printf '%*s' $nrSpacesToAdd)${somma[$nome]} kB\n"
  done
  echo -e "$elenco" | sort -k 2 -n -r
fi
Enter fullscreen mode Exit fullscreen mode

Esempio di output:

$ ./swapUsed.sh 41
java                           94708 kB
apache2                        16188 kB
gnome-software                  8792 kB
chrome                           632 kB
pipewire-pulse                   564 kB
dbus-launch                      452 kB
exim4                            388 kB
dbus-daemon                      388 kB
postgres                          72 kB
(sd-pam)                          64 kB
containerd                        60 kB
spotify                           52 kB
Enter fullscreen mode Exit fullscreen mode

Per usare il comando in Conky, ho aggiunto al file di configurazione .conkyrc le seguenti linee nella sezione conky.text:

...
$hr
${color grey}Name                          Swap used
${color lightgrey}${execi 30 ~/swapUsed.sh 41 | head -n 10}
Enter fullscreen mode Exit fullscreen mode

Questo fa si che il comando venga eseguito ogni 30 secondi con il parametro 41 che specifica la lunghezza delle stringhe corretta per la mia configurazione Conky.
Con head -n 10, indico di stampare solo le prime 10 righe.

Qui il file .conkyrc completo:

-- Conky, a system monitor https://github.com/brndnmtthws/conky
--
-- This configuration file is Lua code. You can write code in here, and it will
-- execute when Conky loads. You can use it to generate your own advanced
-- configurations.
--
-- Try this (remove the `--`):
--
--   print("Loading Conky config")
--
-- For more on Lua, see:
-- https://www.lua.org/pil/contents.html

conky.config = {
    alignment = 'top_right',
    background = false,
    border_width = 1,
    cpu_avg_samples = 2,
    default_color = 'white',
    default_outline_color = 'white',
    default_shade_color = 'white',
    double_buffer = true,
    draw_borders = false,
    draw_graph_borders = true,
    draw_outline = false,
    draw_shades = false,
    extra_newline = false,
    font = 'DejaVu Sans Mono:size=8',
    gap_x = 60,
    gap_y = 60,
    minimum_height = 5,
    minimum_width = 5,
    net_avg_samples = 2,
    no_buffers = true,
    out_to_console = false,
    out_to_ncurses = false,
    out_to_stderr = false,
    out_to_x = true,
    own_window = true,
    own_window_colour = '000000',
    own_window_class = 'Conky',
    own_window_type = 'desktop',
    own_window_transparent = true,
    own_window_argb_visual = true,
    own_window_hints = 'undecorated,below,sticky,skip_taskbar,skip_pager',
    show_graph_range = false,
    show_graph_scale = false,
    stippled_borders = 0,
    update_interval = 5.0,
    uppercase = false,
    use_spacer = 'none',
    use_xft = true,
}

conky.text = [[
${color grey}Uptime:$color $uptime
${color grey}RAM Usage:$color $mem/$memmax - $memperc% ${membar 8}
${color grey}Swap Usage:$color $swap/$swapmax - $swapperc% ${swapbar 8}
${color grey}CPU Usage:$color $cpu% ${cpubar 8}
${color grey}Processes:$color $processes  ${color grey}Running:$color $running_processes
$hr
${color grey}File systems:
 root $color${fs_used /}/${fs_size /} ${fs_bar 8 /}
 ec2-free $color${fs_free /mnt/ec2_export}/${fs_size /mnt/ec2_export} ${fs_bar 8 /mnt/ec2_export}
 qnap $color${fs_used /mnt/u_rsync}/${fs_size /mnt/u_rsync} ${fs_bar 8 /mnt/u_rsync}
${color grey}Networking:
Up:$color ${upspeed} ${color grey} - Down:$color ${downspeed}
$hr
${color grey}Name              PID     CPU%   MEM%
${color lightgrey} ${top name 1} ${top pid 1} ${top cpu 1} ${top mem 1}
${color lightgrey} ${top name 2} ${top pid 2} ${top cpu 2} ${top mem 2}
${color lightgrey} ${top name 3} ${top pid 3} ${top cpu 3} ${top mem 3}
${color lightgrey} ${top name 4} ${top pid 4} ${top cpu 4} ${top mem 4}
${color lightgrey} ${top name 5} ${top pid 5} ${top cpu 5} ${top mem 5}
$hr
${color grey}Name                          Swap used
${color lightgrey}${execi 30 ~/swapUsed.sh 41 | head -n 10}
]]
Enter fullscreen mode Exit fullscreen mode

Image description

Top comments (0)