Stampare un elenco dei processi ordinato per la quantità di swap che usano
Tags: linux, bash, italian
Published: 2023-03-15 22:21:24

Cercando su internet possiamo trovare questo comando per stampare l'elenco dei processi ordinato per uso del file di Swap:

```bash
for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | less
```

Poiché per me è abbastanza magico, ho cercato di capire come funziona:

1. `for file in /proc/*/status` - Ciclo su tutti i file di stato dei processi attualmente in esecuzione. La variabile "file" assume il valore di ogni percorso di file corrispondente.
Il contenuto del file di stato ad es. può essere:

```bash
cat /proc/6377/status
Name:	gnome-software
Umask:	0022
State:	S (sleeping)
Tgid:	6377
Ngid:	0
Pid:	6377
PPid:	6154
TracerPid:	0
Uid:	1000	1000	1000	1000
Gid:	1000	1000	1000	1000
FDSize:	256
Groups:	24 25 27 29 30 33 44 46 106 109 112 114 999 1000 
NStgid:	6377
NSpid:	6377
NSpgid:	6154
NSsid:	6154
VmPeak:	 2922312 kB
VmSize:	 2791180 kB
VmLck:	       0 kB
VmPin:	       0 kB
VmHWM:	  459088 kB
VmRSS:	  163004 kB
RssAnon:	  130664 kB
RssFile:	   32340 kB
RssShmem:	       0 kB
VmData:	  621548 kB
VmStk:	     728 kB
VmExe:	     368 kB
VmLib:	  184796 kB
VmPTE:	    1384 kB
VmSwap:	  218708 kB
HugetlbPages:	       0 kB
CoreDumping:	0
THP_enabled:	1
Threads:	36
SigQ:	2/63374
SigPnd:	0000000000000000
ShdPnd:	0000000000000000
SigBlk:	0000000000000000
SigIgn:	0000000000001000
SigCgt:	0000000100000000
CapInh:	0000000000000000
CapPrm:	0000000000000000
CapEff:	0000000000000000
CapBnd:	000001ffffffffff
CapAmb:	0000000000000000
NoNewPrivs:	0
Seccomp:	0
Seccomp_filters:	0
Speculation_Store_Bypass:	thread vulnerable
SpeculationIndirectBranch:	conditional enabled
Cpus_allowed:	f
Cpus_allowed_list:	0-3
Mems_allowed:	00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list:	0
voluntary_ctxt_switches:	83533
nonvoluntary_ctxt_switches:	8663
```

1. `do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done` - Per ogni percorso del file ($file), viene eseguito il comando awk. Il comando awk cerca le righe che contengono "VmSwap" o "Name" nel file di stato del processo e quindi utilizza il comando "printf" per stampare il secondo e il terzo campo di ogni riga. Nell' esempio del file di stato sopra, troviamo prima Name e poi VmSwap che verranno quindi trovati da awk in questo ordine. Quando la riga contiene Name, il secondo campo corrisponde al nome del processo e il terzo è vuoto. Quando la riga contiene VmSwap, il secondo campo contiene la memoria usata e il terzo l'unità di misura. Alla fine, la clausola "END" viene utilizzata per stampare una riga vuota per separare l'output dei diversi processi.

1. `sort -k 2 -n -r` - Ordina l'output in base al secondo campo (-k 2) in ordine numerico (-n) in ordine inverso (-r).
Significa che la quantità di swap usata dai processi è ordinata dal più grande al più piccolo.

1. `less` - Visualizzare l'output paginato nel terminale.

Es. di output del comando:

```bash
for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | less
gnome-software 218708 kB
mariadbd 155576 kB
code 147548 kB
code 134844 kB
firefox 111212 kB
WebExtensions 71236 kB
java 70472 kB
```

Se vogliamo aggiungere la stampa del Pid possiamo modificare il comando in questo modo:

`for file in /proc/*/status ; do awk '/^(VmSwap:|Name:|Pid:)/ {printf $2 " " $3}END{ print ""}' $file; done | sort -k 3 -n -r | less`

Adesso, il pattern di ricerca usa il carattere ^ che specifica che la corrispondenza deve iniziare esattamente con una delle stringhe specificate.
In questo modo, le righe che iniziano ad es. con "PPid" non vengono selezionate da awk.
Adesso il secondo campo stampato sarà il Pid del processo e il terzo la swap usata.
Il sort lo facciamo quindi sul terzo campo.

Es. di output del comando:

```bash
for file in /proc/*/status ; do awk '/^(VmSwap:|Name:|Pid:)/ {printf $2 " " $3}END{ print ""}' $file; done | sort -k 3 -n -r | less
gnome-software 6377 218708 kB
mariadbd 46522 155576 kB
code 41703 147548 kB
code 40429 134844 kB
firefox 8840 111212 kB
```