Bash: test di sistema “fai da te”

Vi serve uno scriptino facile facile per mettere un po’ sotto torchio il vostro PC? Sì? Cattivi!

Che vi ha fatto di male quel povero mucchietto di ferro e plastica (più sabbia e altri metalli più o meno strambi)? Non basta lo stress a cui lo sottoponete dirottandolo su Faccialibro (cit.) e interminabili serie di selfie e gattini?

Ok, se proprio dovete qui di seguito trovate qualcosa per stressare un po’ la CPU, la RAM ed il disco. Prima il codice e poi ne parliamo:

#!/bin/bash
echo "Crea un gruppo di file di dimensione diversa (totale: circa 4 GB)."
echo "I file contengono dati provenienti da /dev/urandom."
echo "Tipologia di file:"
echo "|# file | Dim. | Tot. |"
echo "|=======|======|======|"
echo "|   1   |   1G |   1G |"
echo "|   2   | 512M |   1G |"
echo "|   3   | 200M | 600M |"
echo "|   4   | 100M | 400M |"
echo "|   20  |   5M | 100M |"
echo "|   50  |   1M |  50M |"
echo "|  1024 |  10K |  10M |"
echo "|  1024 |   1K |   1M |"
echo "|=======|======|======|"
TESTDIR=$HOME/$(date "+%d%m%y-%H%M%S") #crea una cartella nella /home utente con nome nel formato data-ora
# Misura tempo di esecuzione: acquisisci il tempo iniziale TIN
TIN=$(date +'%s')
echo "I file di test saranno creati in $TESTDIR"
mkdir $TESTDIR
echo "Creazione delle sottocartelle, una per ogni dimensione di file..."
for dimfile in "1G" "512M" "200M" "100M" "5M" "1M" "10K" "1K"
do
TARGETDIR=$TESTDIR/$dimfile
echo "Creo $TARGETDIR ..."
mkdir $TARGETDIR
case "$dimfile" in
"1G"     )
numfile=1
blksize=256M # Cerco di far aumentare il consumo di RAM
blkcount=4 # aumentando la dimensione del blocco (4 * 256M = 1G)
;;
"512M"    )
numfile=2
blksize=128M #Come sopra. Blocco grande da 128M
blkcount=4
;;
"200M"    )
numfile=3
blksize=50M # Come sopra.
blkcount=4
;;
"100M"    )
numfile=4
blksize=1M # Da qui in poi blocchi piccoli da 1M, necessariamente!
blkcount=100
;;
"5M"    )
numfile=20
blksize=1M
blkcount=5
;;
"1M"    )
numfile=50
blksize=1M
blkcount=1
;;
"10K"    )
numfile=1024
blksize=1K # Blocchi da 1K
blkcount=10
;;
"1K"    )
numfile=1024
blksize=1K
blkcount=1
;;
esac
index=1
while [ "$index" -le "$numfile" ]
do
echo "Creo $TARGETDIR/file-$dimfile-$index ($index/$numfile)"
dd if=/dev/urandom of=$TARGETDIR/file-$dimfile-$index bs=$blksize count=$blkcount
let "index += 1"
done
done
# Misura tempo di esecuzione: acquisisci il tempo finale TEND
TEND=$(date +'%s')
TTOT=$((TEND-TIN))
# Flusso di dati in MB/s
echo "Tempo totale di esecuzione: $TTOT secondi"
echo "Flusso medio di dati:" $(du -s $TESTDIR | awk '{TMB=($1/1024)/'$TTOT'; printf "%.2f MB/s", TMB}')
echo
echo "Rimuovere la cartella di test $TESTDIR (s/n)?"
read ans
case "$ans" in
"s" | "S" )
echo "Cancello i dati di test..."
rm -rf $TESTDIR
;;
"n" | "N" )
echo "Ok, tieniti il ciarpame in $TESTDIR"
;;
esac
exit

Una specie di “Disclaimer” (e poi lo spiegone)

Lo script ad una prima occhiata potrebbe sembrare lungo e “ommioddiochissàcosacombina”; in realtà è poco più che una lista di “cose da fare”in sequenza cambiando qualche parametro in corso d’opera. A rigore non potrei neanche vendermelo come vero “test delle performance“: sì, l’esecuzione manda il processore a pieno regime, sfrutta un po’ di RAM per le operazioni (merito degli strumenti che utilizzo nello script, non mio) e scrive un mucchietto di ciarpame sul disco… Mmh… quindi tutto sommato è un test delle performance, seppure alla buona, con una misurazione abbozzata e senza operazioni specifiche per i diversi componenti hardware.

script_running

Script in esecuzione

Perché / Cosa / Come

Avevo bisogno un mucchietto di file, non importava il contenuto ma solo la quantità e la dimensione, per chissà quale esperimento. Ho quindi (ovviamente) creato un piccolo script che prendesse delle fettine tagliate a misura del caos di /dev/urandom e le impacchettasse in tanti file: il nocciolo dello script è questo, grazie al multiforme dd.

In questo modo, come da tabellina ad inizio script, ho file assortiti in numero e dimensione la cui elaborazione impegna in maniera diversa il disco: da pochi file grandi (uso “desktop”, spostamento di un file video ad esempio) a molti file piccoli (uso “server”, frequenti accessi al disco, scrittura di file di log) che riducono drasticamente la velocità. L’idea ed il “mix” prendono spunto da vari test simili letti in rete.

Il resto, che permette di variare i parametri passati a dd e, con essi, la dimensione ed il numero dei file generati è ottenuto grazie al costrutto “case... ...esac“, una sorta di menu di scelte e conseguenti azioni da eseguire.

Si potrebbe pensare a case come ad un if...then...elif...fi più compatto e leggibile, in caso di lunghe liste di possibili scelte, ma soprattutto specializzato: case infatti contempla solo l’uguaglianza / disuguaglianza tra il valore della variabile di controllo del costrutto e quelli inseriti in lista.

script_running_bs64M

Script in esecuzione (block size: 64 MB)

Il ciclo for più esterno si occupa di far girare i valori di dimfile, che regola l’esecuzione di case. Il contenuto di ogni sezione definisce quindi il numero di file da creare (numfile) ed i parametri con cui lanciare dd (blksize e blkcount). Questi ultimi sono i veri responsabili del carico di sistema, in quanto indicano a dd il numero e la dimensione dei blocchi di memoria da occupare per accantonare i dati provenienti da urandom, in attesa di scriverli su file.

I dati, come si vede dal grafico sotto, vengono poi scritti a più riprese nei rispettivi file, secondo la velocità del disco (risultato che è uno dei componenti della performance globale).

Script in esecuzione: attività del disco

Insomma, quello che veramente mancherebbe e che mi ero ripromesso di aggiungere prontamente (fingete di crederci, per favore!) è un report meno scarno e meglio preparato (qualche info di sistema, kernel in uso, distribuzione, data/ora, nome utente) e magari dei test aggiuntivi, anche opzionali, da eseguire sui dati creati (spostamento / copia, compressione / decompressione). Magari anche in HTML, magari a colori, magari un’altra volta…

Insomma qualcosa in più per farvi fare con i computerini/oni il surrogato della classica gara tra maschietti adolescenti😀.

Nota finale: fonte per la risposta alla mia esigenza di passare ad awk il valore di una variabile dello script → qui. La necessità di usare awk qui è duplice: innanzitutto estrarre il campo di interesse dall’output di du, e poi fare un calcolo in virgola mobile che bash non sa fare perché opera solo su interi, a differenza ad esempio di zsh. Malgrado la già verificata compatibilità tra le due shell, preferisco comunque riferirmi a bash che è il default della quasi totalità delle distribuzioni Linux. Ad awk e zsh sarà sicuramente dedicato lo spazio che meritano.

Nota finale per davvero: Nel caso voleste far girare lo script più brevemente per un veloce test, generando meno file o solo determinate dimensioni di file, basterà tirare via dal for iniziale i prefissi relativi (ad esempio “1G” e “512M”): così facendo le corrispondenti sezioni di case non verranno mai invocate pur rimanendo presenti. Non toccate nient’altro che altrimenti sfiamma e vi brucia le sopracciglia😮.

Effetti collaterali ovvero il “Teorema della scimmia instancabile”

Conoscete quel teorema (serissimo malgrado quello che il nome farebbe pensare) per cui una scimmia che batta a caso su una tastiera per un tempo sufficientemente lungo, produrrà prima o poi un’opera letteraria esistente? Ecco, quello che vi mostro è un accenno della sua dimostrazione pratica.

effetti_collaterali_dati_random

“Effetti collaterali”

Riempiendo i file con i dati casuali è capitato che alcuni di essi fossero “scambiati” per particolari tipi, prodotti da programmi ben diversi dal semplice dd.

La “colpa” è dei numeri magici, ovvero le sequenze di byte all’inizio di un file che ne identificano il tipo: tramite queste sequenze (non l’estensione!) i sistemi *nix riconoscono i file per ciò che sono.

La mia scimmia si chiama urandom ed è riuscita a produrre molti “finti” file associabili a programmi: provate ad eseguire lo script, magari più volte e vedrete se non salteranno fuori anche a voi cose inaspettate.

Ovviamente il fatto che il magic number sia riconosciuto per qualcosa di noto non implica nulla sul resto del contenuto del file, ma ci si potrebbe divertire a cercare nel disordine altre coincidenze: parole di senso compiuto, sequenze di numeri (una data di nascita, ad esempio), i testi delle canzoni di De Gregori.

Conclusione

Questo script nasce come esercizio di scripting, in particolare sul costrutto case, come in precedenza avevo fatto per gli altri disponibili. Persino alla fine, malgrado un if potesse essere un’alternativa più facile, ho voluto verificare l’uso del “|” per i valori alternativi (“s | S” significa “s oppure S”).

L’altro motivo, non meno importante, per cui gli script dovrebbero nascere è quello di soddisfare un’esigenza costruendosi uno strumento “su misura”: adesso non mi rimane che cercare di ricordare quale fosse questa esigenza

let "post += 1"

# Cioè: Arrivederci al prossimo post!

Informazioni su Man from Mars

https://extendedreality.wordpress.com/

Un Commento

  1. Pingback: Visto nel Web – 139 | Ok, panico

Dimmi che ne pensi o fai "Ciao ciao!" con la manina // Share your thoughts or just say "Hello!"

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: