<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: minnogit</title>
    <description>The latest articles on DEV Community by minnogit (@minnogit).</description>
    <link>https://dev.to/minnogit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F673072%2F4304ed14-f112-401b-bdfd-3d751d9879fb.png</url>
      <title>DEV Community: minnogit</title>
      <link>https://dev.to/minnogit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/minnogit"/>
    <language>en</language>
    <item>
      <title>Come estrarre una singola tabella da un file dump MySQL</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Tue, 19 May 2026 09:08:59 +0000</pubDate>
      <link>https://dev.to/minnogit/come-estrarre-una-singola-tabella-da-un-file-dump-mysql-35jm</link>
      <guid>https://dev.to/minnogit/come-estrarre-una-singola-tabella-da-un-file-dump-mysql-35jm</guid>
      <description>&lt;p&gt;Ti è mai capitato di dover ripristinare &lt;strong&gt;una sola tabella&lt;/strong&gt; ma di avere a disposizione solo un file dump &lt;code&gt;.sql&lt;/code&gt; gigante dell'intero database?&lt;/p&gt;

&lt;p&gt;Invece di perdere tempo cercando di aprire un file da svariati gigabyte con un editor di testo, o peggio, importare tutto il database su un server locale solo per recuperare poche righe, c'è un trucco da riga di comando velocissimo che sfrutta &lt;code&gt;sed&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'/DROP TABLE.*`nome_tabella`/,/UNLOCK TABLES/p'&lt;/span&gt; dump_completo.sql &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; backup_singola_tabella.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otterrai un nuovo file chiamato &lt;code&gt;backup_singola_tabella.sql&lt;/code&gt; contenente esclusivamente la struttura e i dati della tabella che ti interessa.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 Come funziona?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-n&lt;/code&gt;: Dice a &lt;code&gt;sed&lt;/code&gt; di non stampare nulla di default (evita di intasare il terminale).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-e&lt;/code&gt;: Specifica il pattern di espressione da eseguire.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;'/DROP TABLE.*\&lt;/code&gt;tabella&lt;code&gt;/,/UNLOCK TABLES/p'&lt;/code&gt;: Definisce un intervallo di testo. Dice a &lt;code&gt;sed&lt;/code&gt;: &lt;em&gt;"Inizia a copiare quando trovi l'istruzione &lt;code&gt;DROP TABLE&lt;/code&gt;per la tabella &lt;code&gt;tabella&lt;/code&gt; e fermati non appena incontri il primo&lt;code&gt;UNLOCK TABLES&lt;/code&gt;"&lt;/em&gt;. La &lt;code&gt;p&lt;/code&gt; finale sta per &lt;em&gt;print&lt;/em&gt; (stampa).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;gt;&lt;/code&gt;: Reindirizza tutto il testo estratto in un nuovo file pulito.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⚠️ Un dettaglio a cui fare attenzione
&lt;/h2&gt;

&lt;p&gt;Questo metodo si basa sulla struttura standard di &lt;code&gt;mysqldump&lt;/code&gt;, dove ogni tabella inizia con il blocco &lt;code&gt;DROP TABLE ...&lt;/code&gt; e termina con &lt;code&gt;UNLOCK TABLES&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Se il tuo dump è stato generato con tool di terze parti o con opzioni particolari (ad esempio disabilitando i blocchi delle tabelle o i drop), verifica i marker iniziali e finali nel file per adattare l'intervallo di &lt;code&gt;sed&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>sql</category>
    </item>
    <item>
      <title>Stabilizzazione dell'Infrastruttura: Gestire il Connection Pooling tra Proxy e Backend</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Mon, 18 May 2026 13:58:20 +0000</pubDate>
      <link>https://dev.to/minnogit/stabilizzazione-dellinfrastruttura-gestire-il-connection-pooling-tra-proxy-e-backend-amg</link>
      <guid>https://dev.to/minnogit/stabilizzazione-dellinfrastruttura-gestire-il-connection-pooling-tra-proxy-e-backend-amg</guid>
      <description>&lt;p&gt;Nel mantenimento di architetture web complesse, l'ottimizzazione del dialogo tra il Proxy (nel nostro caso Apache) e i nodi di backend è un passaggio cruciale per garantire la fluidità dei servizi. Recentemente abbiamo analizzato una situazione di saturazione delle risorse che ci ha permesso di approfondire la gestione dei socket TCP, il comportamento dei pool di connessione e la complessa natura dei timeout multilivello.&lt;/p&gt;

&lt;p&gt;In questo articolo vedremo come abbiamo identificato il problema, gli strumenti di monitoraggio utilizzati e come configurare correttamente i timeout per proteggere il proxy, senza penalizzare i portali che richiedono elaborazioni lunghe.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. I primi segnali: Errori di Fork
&lt;/h2&gt;

&lt;p&gt;Il punto di partenza della nostra analisi non è stato un crash, ma una serie di messaggi nei log di Apache che indicavano difficoltà nel gestire nuovi processi:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[error] (11)Resource temporarily unavailable: apr_thread_create: unable to create worker thread&lt;/code&gt;&lt;br&gt;
&lt;code&gt;[error] (11)Resource temporarily unavailable: fork: avocado_create: pool_task&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Questi &lt;strong&gt;errori di fork&lt;/strong&gt; compaiono quando il server raggiunge i limiti imposti dal sistema operativo o dalla configurazione dell'MPM (Multi-Processing Module). I worker esistenti rimangono occupati troppo a lungo, impedendo la creazione di nuovi thread per servire le nuove richieste in ingresso.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Monitoraggio e Analisi del Traffico
&lt;/h2&gt;

&lt;p&gt;Per capire perché Apache stesse saturando i worker, abbiamo utilizzato alcuni comandi shell per analizzare lo stato delle connessioni di rete in tempo reale.&lt;/p&gt;
&lt;h3&gt;
  
  
  Analisi quantitativa per backend
&lt;/h3&gt;

&lt;p&gt;Per osservare come variava il carico verso un nodo specifico (nel nostro caso il &lt;code&gt;.106&lt;/code&gt;), abbiamo utilizzato un monitoraggio continuo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;watch &lt;span class="nt"&gt;-n&lt;/span&gt; 1 &lt;span class="s2"&gt;"netstat -atpn | grep 172.31.41.106 | wc -l"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo comando ci ha permesso di notare che il numero di connessioni non scalava verso il basso come previsto, indicando una persistenza anomala dei socket.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analisi della distribuzione delle connessioni
&lt;/h3&gt;

&lt;p&gt;Un altro comando fondamentale è stato quello per mappare la provenienza del traffico e identificare eventuali anomalie nella distribuzione dei client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netstat &lt;span class="nt"&gt;-ntu&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $5}'&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;: &lt;span class="nt"&gt;-f1&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;L'analisi dettagliata ha rivelato un numero elevato di connessioni in stato &lt;strong&gt;CLOSE_WAIT&lt;/strong&gt;. Questo stato indica che il backend ha già terminato la sua parte di connessione, ma il proxy non ha ancora chiuso il socket lato suo. Un vero e proprio "limbo" TCP.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Disaccoppiare i Timeout: Applicazione vs Infrastruttura
&lt;/h2&gt;

&lt;p&gt;Per risolvere questo scenario, è fondamentale fare chiarezza sulla differenza tra due concetti spesso confusi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Timeout Applicativo:&lt;/strong&gt; È il tempo richiesto dal codice sorgente per completare un'operazione (es. una query complessa o la generazione di un file pesante). Un timeout applicativo troppo lungo espone il server al pericolo di elaborazioni infinite, mantenendo il backend occupato e saturando le risorse computazionali.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timeout Infrastrutturale (o di Rete):&lt;/strong&gt; È il tempo massimo concesso per la trasmissione dei dati e la gestione dei socket tra i vari nodi della rete.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il problema esaminato in questa analisi riguardava specificamente il &lt;strong&gt;timeout della comunicazione infrastrutturale tra il proxy e l'applicazione&lt;/strong&gt;, ovvero i socket rimasti orfani che bloccavano i thread di Apache. L'implementazione applicativa interna al backend è ininfluente: che si tratti di un'architettura o di un'altra, se la gestione del socket TCP lato proxy fallisce, l'infrastruttura si satura.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Il Limite di Apache Balancer Manager: Timeout per Route
&lt;/h2&gt;

&lt;p&gt;Durante le indagini abbiamo esplorato la possibilità di creare configurazioni di timeout differenziate a seconda della route (URL path), in modo da isolare i percorsi più lenti da quelli più veloci.&lt;/p&gt;

&lt;p&gt;Tuttavia, abbiamo riscontrato un limite strutturale: &lt;strong&gt;il modulo Balancer Manager di Apache condivide il timeout del proxy per tutte le route&lt;/strong&gt;. Non è un parametro sovrascrivibile o granularizzabile a livello di singolo membro del cluster o di specifico path all'interno dello stesso contesto di bilanciamento. Di conseguenza, la strategia di gestione dei timeout deve essere applicata in modo uniforme all'intero blocco del proxy.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. La Soluzione: Il Ruolo di &lt;code&gt;connectiontimeout&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;In molti dei nostri portali è indispensabile mantenere timeout globali alti per consentire l'esecuzione di script applicativi lunghi ed elaborazioni pesanti. Abbassare indiscriminatamente il timeout del proxy avrebbe interrotto servizi legittimi.&lt;/p&gt;

&lt;p&gt;La soluzione definitiva che ha azzerato i &lt;code&gt;CLOSE_WAIT&lt;/code&gt; e risolto gli errori di fork, pur mantenendo il supporto agli script lunghi, è stata il passaggio alla sintassi &lt;code&gt;balancer://&lt;/code&gt; sfruttando il parametro &lt;strong&gt;&lt;code&gt;connectiontimeout&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configurazione applicata:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;Proxy&lt;/span&gt;&lt;span class="sr"&gt; balancer://frontoffice&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="c"&gt;# node04 - Configurazione ottimizzata&lt;/span&gt;
    &lt;span class="nc"&gt;BalancerMember&lt;/span&gt; http://172.31.41.106:8080 route=4 connectiontimeout=2 retry=10 hcmethod=TCP hcinterval=5 hcpasses=2 hcfails=1

    &lt;span class="nc"&gt;ProxySet&lt;/span&gt; lbmethod=bybusyness
    &lt;span class="nc"&gt;ProxySet&lt;/span&gt; stickysession=ROUTEID
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="nc"&gt;ProxyPass&lt;/span&gt; "/" "balancer://frontoffice/"
&lt;span class="nc"&gt;ProxyPassReverse&lt;/span&gt; "/" "balancer://frontoffice/"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Perché questa configurazione è risolutiva?
&lt;/h3&gt;

&lt;p&gt;Il segreto sta nella separazione tra il timeout di risposta globale e il timeout di connessione iniziale:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;connectiontimeout=2&lt;/code&gt; (La vera protezione)&lt;/strong&gt;: Questo parametro agisce solo sulla fase di handshake TCP iniziale. Se il backend è congestionato, bloccato o non risponde entro 2 secondi, Apache desiste immediatamente e libera il proprio worker. Questo previene l'accumulo di processi appesi in Apache che causavano gli errori di fork.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mantenimento degli script lunghi&lt;/strong&gt;: Una volta stabilita la connessione nei primi 2 secondi, il proxy concede all'applicazione tutto il tempo configurato nel timeout globale per terminare le sue elaborazioni pesanti.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health Checks attivi (&lt;code&gt;hcinterval=5&lt;/code&gt;)&lt;/strong&gt;: Apache interroga il backend ogni 5 secondi. Se un nodo fallisce i controlli TCP, viene temporaneamente isolato dal cluster, evitando di inviare traffico a un server saturo.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  6. Conclusioni e Manutenzione Futura
&lt;/h2&gt;

&lt;p&gt;La risoluzione degli errori di fork ci ha ricordato che la stabilità di un'infrastruttura non richiede di sacrificare le necessità dell'applicazione (come le elaborazioni lunghe), ma richiede di configurare correttamente i limiti della rete.&lt;/p&gt;

&lt;p&gt;Per evitare derive configurative e mantenere l'uniformità su tutta la flotta di server, la distribuzione di queste direttive &lt;code&gt;BalancerMember&lt;/code&gt; e la gestione dei relativi VirtualHost verrà centralizzata e gestita tramite &lt;strong&gt;Puppet Server&lt;/strong&gt;. L'automazione è l'unica via per garantire che queste best practice rimangano stabili e documentate nel tempo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cheat Sheet di Emergenza per il futuro:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Isolamento rapido:&lt;/strong&gt; &lt;code&gt;netstat -atpn | grep CLOSE_WAIT&lt;/code&gt; per contare i socket orfani.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analisi client:&lt;/strong&gt; &lt;code&gt;netstat -ntu | awk '{print $5}' ...&lt;/code&gt; per verificare la distribuzione degli IP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regola d'oro:&lt;/strong&gt; Separare sempre il tempo concesso all'applicazione per elaborare i dati dal tempo concesso alla rete per aprire la connessione (&lt;code&gt;connectiontimeout&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>devops</category>
      <category>linux</category>
    </item>
    <item>
      <title>Watchdog Apache con Bash, Cron e Systemd: monitoraggio automatico di memoria, PID e socket close-wait</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Mon, 18 May 2026 11:18:27 +0000</pubDate>
      <link>https://dev.to/minnogit/watchdog-apache-con-bash-cron-e-systemd-monitoraggio-automatico-di-memoria-pid-e-socket-4eoa</link>
      <guid>https://dev.to/minnogit/watchdog-apache-con-bash-cron-e-systemd-monitoraggio-automatico-di-memoria-pid-e-socket-4eoa</guid>
      <description>&lt;p&gt;In alcuni scenari ad alto carico o in presenza di problemi lato backend, Apache può degradare progressivamente fino a diventare lento, saturare le risorse o smettere di rispondere correttamente.&lt;/p&gt;

&lt;p&gt;Per mitigare questo tipo di problemi è possibile implementare un watchdog leggero in Bash che:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;monitora periodicamente lo stato del sistema;&lt;/li&gt;
&lt;li&gt;verifica alcune metriche critiche;&lt;/li&gt;
&lt;li&gt;esegue automaticamente un &lt;code&gt;reload&lt;/code&gt; o un &lt;code&gt;restart&lt;/code&gt; di Apache;&lt;/li&gt;
&lt;li&gt;registra gli eventi tramite &lt;code&gt;syslog&lt;/code&gt; e &lt;code&gt;journalctl&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Questo approccio è particolarmente utile in ambienti:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;con reverse proxy Apache;&lt;/li&gt;
&lt;li&gt;con backend applicativi instabili;&lt;/li&gt;
&lt;li&gt;con leak di connessioni;&lt;/li&gt;
&lt;li&gt;dove è necessario un meccanismo di self-healing semplice e trasparente.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Obiettivo dello script
&lt;/h1&gt;

&lt;p&gt;Lo script controlla:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;RAM disponibile;&lt;/li&gt;
&lt;li&gt;numero di PID usati dal servizio Apache;&lt;/li&gt;
&lt;li&gt;connessioni TCP in stato &lt;code&gt;close-wait&lt;/code&gt; verso un backend specifico;&lt;/li&gt;
&lt;li&gt;health check HTTP locale;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In base alle soglie configurate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;esegue un &lt;code&gt;reload&lt;/code&gt; di Apache;&lt;/li&gt;
&lt;li&gt;oppure un &lt;code&gt;restart&lt;/code&gt; completo;&lt;/li&gt;
&lt;li&gt;scrive i dettagli nel journal di systemd.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Script completo
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# --- PARAMETRI DI SOGLIA ---&lt;/span&gt;
&lt;span class="nv"&gt;SOGLIA_RAM_FREE_MB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100
&lt;span class="nv"&gt;SOGLIA_PIDS_PERCENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60
SOGLIA_close-wait&lt;span class="o"&gt;=&lt;/span&gt;300

&lt;span class="c"&gt;# --- RACCOLTA DATI ---&lt;/span&gt;
&lt;span class="c"&gt;# Usiamo percorsi assoluti per cron e variabili pulite&lt;/span&gt;
&lt;span class="nv"&gt;RAM_DISPONIBILE_MB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;/usr/bin/free &lt;span class="nt"&gt;-m&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;Mem | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $7}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Conteggio in tempo reale delle connessioni orfane in close-wait&lt;/span&gt;
close-wait_COUNT&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;/usr/bin/ss &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="nt"&gt;-tanp&lt;/span&gt; state close-wait | /usr/bin/wc &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Gestione PIDs con controllo esistenza file (evita errori se Apache è spento)&lt;/span&gt;
&lt;span class="nv"&gt;PIDS_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/sys/fs/cgroup/system.slice/apache2.service/pids.current"&lt;/span&gt;
&lt;span class="nv"&gt;MAX_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/sys/fs/cgroup/system.slice/apache2.service/pids.max"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PIDS_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;CURRENT_APACHE_PIDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PIDS_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;MAX_APACHE_PIDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MAX_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Se MAX è la stringa "max", o è 0, o è vuoto -&amp;gt; la percentuale è 0 (limite infinito)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MAX_APACHE_PIDS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"max"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MAX_APACHE_PIDS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MAX_APACHE_PIDS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;PERCENTUAL_PIDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nv"&gt;PERCENTUAL_PIDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; CURRENT_APACHE_PIDS &lt;span class="o"&gt;/&lt;/span&gt; MAX_APACHE_PIDS &lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;fi
else
    &lt;/span&gt;&lt;span class="nv"&gt;PERCENTUAL_PIDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# --- LOGICA DI CONTROLLO ---&lt;/span&gt;
&lt;span class="nv"&gt;AZIONE_NECESSARIA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false
&lt;/span&gt;&lt;span class="nv"&gt;TIPO_AZIONE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"reload"&lt;/span&gt; &lt;span class="c"&gt;# Default&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RAM_DISPONIBILE_MB&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SOGLIA_RAM_FREE_MB&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;MOTIVO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"RAM bassa (&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RAM_DISPONIBILE_MB&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;MB)"&lt;/span&gt;
    &lt;span class="nv"&gt;AZIONE_NECESSARIA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
    &lt;/span&gt;&lt;span class="nv"&gt;TIPO_AZIONE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"restart"&lt;/span&gt; &lt;span class="c"&gt;# Se la RAM è finita, il reload è troppo lento&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PERCENTUAL_PIDS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SOGLIA_PIDS_PERCENT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;MOTIVO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PIDs al &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PERCENTUAL_PIDS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% (&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CURRENT_APACHE_PIDS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MAX_APACHE_PIDS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
    &lt;span class="nv"&gt;AZIONE_NECESSARIA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
    &lt;/span&gt;&lt;span class="nv"&gt;TIPO_AZIONE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"reload"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$close&lt;/span&gt;&lt;span class="s2"&gt;-wait_COUNT"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SOGLIA_close&lt;/span&gt;&lt;span class="s2"&gt;-wait"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;MOTIVO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Rilevato leak di socket (&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;close&lt;/span&gt;&lt;span class="p"&gt;-wait_COUNT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; connessioni in close-wait)"&lt;/span&gt;
    &lt;span class="nv"&gt;AZIONE_NECESSARIA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
    &lt;/span&gt;&lt;span class="nv"&gt;TIPO_AZIONE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"reload"&lt;/span&gt; &lt;span class="c"&gt;# Il reload è sufficiente a liberare i socket orfani&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Check sopravvivenza: se Apache non risponde, forza RESTART a prescindere dalle soglie&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; /usr/bin/curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--max-time&lt;/span&gt; 5 http://127.0.0.1/ &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;MOTIVO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Apache non risponde (Health Check fallito)"&lt;/span&gt;
    &lt;span class="nv"&gt;AZIONE_NECESSARIA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
    &lt;/span&gt;&lt;span class="nv"&gt;TIPO_AZIONE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"restart"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# --- AZIONE ---&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;$AZIONE_NECESSARIA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;: Allarme: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MOTIVO&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. Eseguo &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TIPO_AZIONE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
    /usr/bin/logger &lt;span class="nt"&gt;-t&lt;/span&gt; apache_health_watchdog &lt;span class="s2"&gt;"Allarme: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MOTIVO&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. Eseguo &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TIPO_AZIONE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TIPO_AZIONE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"reload"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        /usr/bin/systemctl reload apache2

        &lt;span class="c"&gt;# Se il reload fallisce (es. kernel già in fork rejected), prova il restart&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
            /usr/bin/logger &lt;span class="nt"&gt;-t&lt;/span&gt; apache_health_watchdog &lt;span class="s2"&gt;"Reload fallito, forzo restart."&lt;/span&gt;
            /usr/bin/systemctl restart apache2
        &lt;span class="k"&gt;fi
    else&lt;/span&gt;
        /usr/bin/systemctl restart apache2
    &lt;span class="k"&gt;fi
fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Installazione
&lt;/h1&gt;

&lt;p&gt;Salvare lo script in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/local/sbin/check_system_health.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rendere il file eseguibile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/sbin/check_system_health.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Configurazione del cron
&lt;/h1&gt;

&lt;p&gt;Aggiungere in &lt;code&gt;/etc/crontab&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*/2 * * * * root flock -n /tmp/apache_watchdog.lock /usr/local/sbin/check_system_health.sh &amp;gt;&amp;gt; /var/log/apache_health_watchdog.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo esegue il controllo ogni 2 minuti.&lt;/p&gt;

&lt;h2&gt;
  
  
  Perché usare &lt;code&gt;flock&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;flock&lt;/code&gt; evita esecuzioni concorrenti dello script.&lt;/p&gt;

&lt;p&gt;In condizioni di degrado del sistema:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;un controllo potrebbe impiegare più tempo del previsto;&lt;/li&gt;
&lt;li&gt;il cron successivo potrebbe partire mentre il precedente è ancora attivo;&lt;/li&gt;
&lt;li&gt;si rischiano reload o restart multipli contemporanei.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Con:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flock &lt;span class="nt"&gt;-n&lt;/span&gt; /tmp/apache_watchdog.lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;solo una istanza dello script può essere eseguita alla volta.&lt;/p&gt;




&lt;h1&gt;
  
  
  Analisi delle metriche monitorate
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. RAM disponibile
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;free &lt;span class="nt"&gt;-m&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo script utilizza:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $7}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;che corrisponde alla colonna &lt;code&gt;available&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Se la memoria disponibile scende sotto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SOGLIA_RAM_FREE_MB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;viene eseguito un restart completo di Apache.&lt;/p&gt;

&lt;p&gt;Questo è utile perché:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;il &lt;code&gt;reload&lt;/code&gt; può richiedere fork aggiuntivi;&lt;/li&gt;
&lt;li&gt;in condizioni di memoria critica il reload potrebbe peggiorare la situazione;&lt;/li&gt;
&lt;li&gt;un restart libera immediatamente worker e memoria frammentata.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Saturazione PID Apache
&lt;/h2&gt;

&lt;p&gt;Lo script legge direttamente i contatori cgroup di systemd:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/sys/fs/cgroup/system.slice/apache2.service/pids.current
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/sys/fs/cgroup/system.slice/apache2.service/pids.max
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo approccio è molto più affidabile rispetto al parsing di &lt;code&gt;ps&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Se il servizio supera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;SOGLIA_PIDS_PERCENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;viene eseguito un &lt;code&gt;reload&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Questo permette di:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rigenerare worker;&lt;/li&gt;
&lt;li&gt;liberare processi stuck;&lt;/li&gt;
&lt;li&gt;evitare il raggiungimento del limite massimo PID.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Socket close-wait
&lt;/h2&gt;

&lt;p&gt;Lo stato &lt;code&gt;close-wait&lt;/code&gt; indica:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;il peer remoto ha chiuso la connessione;&lt;/li&gt;
&lt;li&gt;il processo locale non ha ancora rilasciato il socket.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Molte connessioni in &lt;code&gt;close-wait&lt;/code&gt; possono indicare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;leak applicativi;&lt;/li&gt;
&lt;li&gt;backend instabili;&lt;/li&gt;
&lt;li&gt;worker Apache bloccati;&lt;/li&gt;
&lt;li&gt;timeout mal configurati.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lo script utilizza:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ss &lt;span class="nt"&gt;-tanp&lt;/span&gt; state close-wait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo approccio è preferibile rispetto a &lt;code&gt;netstat&lt;/code&gt; perché:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ss&lt;/code&gt; è più moderno;&lt;/li&gt;
&lt;li&gt;usa meno CPU;&lt;/li&gt;
&lt;li&gt;legge direttamente dal kernel tramite netlink;&lt;/li&gt;
&lt;li&gt;è più affidabile sotto alto carico;&lt;/li&gt;
&lt;li&gt;evita dipendenze da &lt;code&gt;net-tools&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se il numero supera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SOGLIA_close-wait&lt;span class="o"&gt;=&lt;/span&gt;300
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;viene eseguito un &lt;code&gt;reload&lt;/code&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Logging e monitoraggio
&lt;/h1&gt;

&lt;p&gt;Lo script utilizza:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;logger &lt;span class="nt"&gt;-t&lt;/span&gt; apache_health_watchdog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quindi gli eventi sono consultabili tramite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-t&lt;/span&gt; apache_health_watchdog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esempio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;May 18 10:42:01 server apache_health_watchdog: Allarme: Rilevato leak di socket (182 connessioni in close-wait). Eseguo reload.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Per seguire i log in tempo reale:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; apache_health_watchdog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Quando usare questo approccio
&lt;/h1&gt;

&lt;p&gt;Questo watchdog è particolarmente utile quando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apache funge da reverse proxy;&lt;/li&gt;
&lt;li&gt;i backend possono bloccarsi o degradare;&lt;/li&gt;
&lt;li&gt;non è disponibile un orchestratore avanzato;&lt;/li&gt;
&lt;li&gt;si vuole una soluzione semplice e immediata;&lt;/li&gt;
&lt;li&gt;si desidera un meccanismo di self-healing leggero.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Limiti della soluzione
&lt;/h1&gt;

&lt;p&gt;Questo approccio non sostituisce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;un monitoraggio completo;&lt;/li&gt;
&lt;li&gt;metriche Prometheus/Grafana;&lt;/li&gt;
&lt;li&gt;tracing applicativo;&lt;/li&gt;
&lt;li&gt;analisi root cause;&lt;/li&gt;
&lt;li&gt;tuning corretto di Apache e backend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il watchdog serve principalmente come:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mitigazione automatica;&lt;/li&gt;
&lt;li&gt;protezione operativa;&lt;/li&gt;
&lt;li&gt;recovery rapido.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>automation</category>
      <category>devops</category>
      <category>linux</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Eseguire Backup grandi su Debian: Compressione, Split e Sessioni Persistenti</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Fri, 23 Jan 2026 15:52:34 +0000</pubDate>
      <link>https://dev.to/minnogit/eseguire-backup-grandi-su-debian-compressione-split-e-sessioni-persistenti-17c7</link>
      <guid>https://dev.to/minnogit/eseguire-backup-grandi-su-debian-compressione-split-e-sessioni-persistenti-17c7</guid>
      <description>&lt;p&gt;Gestire dataset massivi (100GB+) su un server remoto presenta due sfide principali: la &lt;strong&gt;gestione delle risorse&lt;/strong&gt; (RAM/CPU) e la &lt;strong&gt;stabilità della connessione&lt;/strong&gt;. Se la sessione SSH cade mentre stai creando un archivio enorme, il processo viene interrotto bruscamente, obbligandoti a ricominciare da capo.&lt;/p&gt;

&lt;p&gt;In questa guida vedremo come usare &lt;code&gt;7-Zip&lt;/code&gt; per creare archivi multi-volume e come proteggere il processo con &lt;code&gt;screen&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Il problema della disconnessione SSH
&lt;/h2&gt;

&lt;p&gt;Quando avvii un comando tramite SSH, questo è legato alla tua sessione. Se la tua connessione internet vacilla o chiudi il terminale, il sistema invia un segnale di "hangup" (SIGHUP) e interrompe il lavoro. Per un backup di molto grande che può richiedere ore, questo è un rischio inaccettabile.&lt;/p&gt;

&lt;h3&gt;
  
  
  La soluzione: GNU Screen
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;screen&lt;/code&gt; è un multiplexer di terminale che permette di avviare un processo in una sessione virtuale che sopravvive anche se ti disconnetti.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installazione:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;screen p7zip-full

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Flusso di lavoro con Screen
&lt;/h2&gt;

&lt;p&gt;Prima di lanciare il comando di compressione, crea una sessione dedicata:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Crea una sessione:&lt;/strong&gt; &lt;code&gt;screen -S backup_cliente&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lancia il comando di compressione&lt;/strong&gt; (vedi sezione successiva).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scollegati (Detach):&lt;/strong&gt; Premi &lt;code&gt;CTRL + A&lt;/code&gt; e poi il tasto &lt;code&gt;D&lt;/code&gt;. Ora puoi chiudere il terminale e spegnere il tuo PC; il server continuerà a lavorare.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ricollegati (Resume):&lt;/strong&gt; Quando vuoi controllare l'avanzamento, torna nel terminale e scrivi:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;screen &lt;span class="nt"&gt;-r&lt;/span&gt; backup_cliente

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Il comando 7-Zip ottimizzato (Low RAM)
&lt;/h2&gt;

&lt;p&gt;Per evitare che il server vada in crash per esaurimento memoria (OOM Error), utilizziamo parametri che limitano l'uso della RAM e della CPU:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;7z a &lt;span class="nt"&gt;-v1g&lt;/span&gt; &lt;span class="nt"&gt;-mx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;-md&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;16m &lt;span class="nt"&gt;-mmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2 &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-mhe&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;on archive_name.7z ./source_folder/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Analisi dei parametri:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;a&lt;/code&gt;&lt;/strong&gt;: Aggiunge i file all'archivio.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-v1g&lt;/code&gt;&lt;/strong&gt;: Divide l'archivio in parti da &lt;strong&gt;1GB&lt;/strong&gt; (ideale per upload/download FTP stabili).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-mx=1&lt;/code&gt;&lt;/strong&gt;: Compressione minima (ultra-rapida). Fondamentale per risparmiare tempo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-md=16m&lt;/code&gt;&lt;/strong&gt;: Riduce il "dizionario" di compressione a 16MB per mantenere basso l'uso della RAM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-mmt=2&lt;/code&gt;&lt;/strong&gt;: Limita l'uso a 2 thread della CPU.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-p&lt;/code&gt;&lt;/strong&gt;: Richiede una password in modo sicuro (non apparirà in chiaro nei log).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-mhe=on&lt;/code&gt;&lt;/strong&gt;: Cifra anche i nomi dei file (senza password non si vede il contenuto).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Verifica e Consegna al Cliente
&lt;/h2&gt;

&lt;p&gt;Una volta terminato, verifica l'integrità dei volumi prima di caricarli sull'FTP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;7z t archive_name.7z.001

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Istruzioni per il cliente:&lt;/strong&gt;&lt;br&gt;
Comunica al destinatario che per estrarre i dati dovrà:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scaricare &lt;strong&gt;tutti&lt;/strong&gt; i file (&lt;code&gt;.001&lt;/code&gt;, &lt;code&gt;.002&lt;/code&gt;, ... fino al file &lt;code&gt;.7z&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Usare software come &lt;strong&gt;7-Zip&lt;/strong&gt; (Windows).&lt;/li&gt;
&lt;li&gt;Aprire esclusivamente il primo file della serie; il programma ricomporrà automaticamente l'intero archivio.&lt;/li&gt;
&lt;/ol&gt;




</description>
      <category>linux</category>
    </item>
    <item>
      <title>Ripristinare il backup di un database PostgreSQL su AWS senza accesso diretto al server DB</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Tue, 20 Jan 2026 18:25:27 +0000</pubDate>
      <link>https://dev.to/minnogit/ripristinare-il-backup-di-un-database-postgresql-su-aws-senza-accesso-diretto-al-server-db-3gf0</link>
      <guid>https://dev.to/minnogit/ripristinare-il-backup-di-un-database-postgresql-su-aws-senza-accesso-diretto-al-server-db-3gf0</guid>
      <description>&lt;p&gt;In molte infrastrutture AWS ben progettate, il server PostgreSQL &lt;strong&gt;non è esposto su Internet&lt;/strong&gt;:&lt;br&gt;
non ha un IP pubblico statico e &lt;strong&gt;non è accessibile direttamente via SSH&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Il database risiede in una &lt;strong&gt;subnet privata&lt;/strong&gt; all’interno di una &lt;strong&gt;VPC&lt;/strong&gt;, mentre l’accesso avviene tramite un &lt;strong&gt;server ponte (jump host / bastion host)&lt;/strong&gt; con IP pubblico.&lt;/p&gt;

&lt;p&gt;In questo articolo vediamo &lt;strong&gt;come ripristinare un database PostgreSQL partendo da un file &lt;code&gt;.sql&lt;/code&gt; presente sul proprio PC&lt;/strong&gt;, analizzando &lt;strong&gt;le diverse soluzioni possibili&lt;/strong&gt;, i &lt;strong&gt;pro e contro&lt;/strong&gt;, e raccogliendo in fondo una serie di &lt;strong&gt;comandi PostgreSQL di uso comune&lt;/strong&gt; come note operative.&lt;/p&gt;


&lt;h2&gt;
  
  
  Scenario di riferimento
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PC locale&lt;/strong&gt;: Debian Linux, con file &lt;code&gt;db.sql&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server ponte&lt;/strong&gt;: accessibile via SSH con chiave (&lt;code&gt;serverponte.dominioaziendale.it&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Server PostgreSQL&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debian&lt;/li&gt;
&lt;li&gt;IP privato statico (es. &lt;code&gt;serverpostgresql.ipprivato.domioaziendale.it&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Accessibile solo dalla VPC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Utenti DB disponibili&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;postgres&lt;/code&gt; (superuser)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;admin&lt;/code&gt; (utente applicativo)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Obiettivo&lt;/strong&gt;: ripristinare il database &lt;code&gt;NomeDB&lt;/code&gt; da script SQL&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Problema tipico
&lt;/h2&gt;

&lt;p&gt;Lo script SQL &lt;strong&gt;non viene eseguito correttamente usando DBeaver&lt;/strong&gt; con l’utente &lt;code&gt;admin&lt;/code&gt; e produce errori come:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;permessi insufficienti&lt;/li&gt;
&lt;li&gt;impossibilità di creare estensioni&lt;/li&gt;
&lt;li&gt;errori su &lt;code&gt;OWNER TO postgres&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;messaggi legati a &lt;code&gt;pg_hba.conf&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Questo accade perché &lt;strong&gt;un file &lt;code&gt;.sql&lt;/code&gt; spesso contiene operazioni da superuser&lt;/strong&gt;, anche se il database esiste già.&lt;/p&gt;


&lt;h2&gt;
  
  
  Le possibili soluzioni
&lt;/h2&gt;
&lt;h3&gt;
  
  
  ✔️ Soluzione 1 – Tunnel SSH + &lt;code&gt;psql&lt;/code&gt; locale (consigliata)
&lt;/h3&gt;

&lt;p&gt;È la soluzione &lt;strong&gt;più pulita, sicura e professionale&lt;/strong&gt;.&lt;br&gt;
Non richiede di copiare file sui server e sfrutta il port forwarding SSH.&lt;/p&gt;
&lt;h3&gt;
  
  
  Schema logico
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PC locale → tunnel SSH → server ponte → rete privata → PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Apertura del tunnel
&lt;/h3&gt;

&lt;p&gt;Dal &lt;strong&gt;PC locale&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-L&lt;/span&gt; 5433:serverpostgresql.ipprivato.domioaziendale.it:5432 serverponte.dominioaziendale.it
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;5433&lt;/code&gt; → porta locale&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;5432&lt;/code&gt; → porta PostgreSQL remota&lt;/li&gt;
&lt;li&gt;il tunnel resta attivo finché la sessione SSH è aperta&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ripristino del database
&lt;/h3&gt;

&lt;p&gt;In un &lt;strong&gt;secondo terminale locale&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-p&lt;/span&gt; 5433 &lt;span class="nt"&gt;-U&lt;/span&gt; admin &lt;span class="nt"&gt;-d&lt;/span&gt; NomeDB &amp;lt; db.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ In questo scenario l’utente &lt;code&gt;admin&lt;/code&gt; &lt;strong&gt;deve essere SUPERUSER&lt;/strong&gt;, altrimenti lo script potrebbe fallire.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✔️ Soluzione 2 – Promuovere temporaneamente &lt;code&gt;admin&lt;/code&gt; a superuser
&lt;/h3&gt;

&lt;p&gt;Se &lt;code&gt;pg_hba.conf&lt;/code&gt; blocca le connessioni dell’utente &lt;code&gt;postgres&lt;/code&gt; da remoto (caso molto comune in ambienti gestiti con Puppet), la soluzione più pragmatica è:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="k"&gt;admin&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;SUPERUSER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dopo il ripristino:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="k"&gt;admin&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;NOSUPERUSER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✔️ Veloce&lt;br&gt;
✔️ Non richiede modifiche a &lt;code&gt;pg_hba.conf&lt;/code&gt;&lt;br&gt;
✔️ Adatta a interventi manuali controllati&lt;/p&gt;


&lt;h3&gt;
  
  
  ✔️ Soluzione 3 – Copiare il file sul server DB ed eseguire localmente
&lt;/h3&gt;

&lt;p&gt;Indicata per file molto grandi o connessioni instabili.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp db.sql serverponte.dominioaziendale.it:/tmp/
&lt;span class="c"&gt;# poi dal jump host verso il DB&lt;/span&gt;
scp /tmp/db.sql serverpostgresql.ipprivato.domioaziendale.it:/tmp/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sul server DB:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su - postgres
psql NomeDB &amp;lt; /tmp/db.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✔️ Massima affidabilità&lt;br&gt;
❌ Più passaggi manuali&lt;/p&gt;


&lt;h2&gt;
  
  
  Perché DBeaver spesso non basta
&lt;/h2&gt;

&lt;p&gt;DBeaver funziona bene per:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;restore da dump binari&lt;/li&gt;
&lt;li&gt;operazioni standard&lt;/li&gt;
&lt;li&gt;utenti applicativi&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ma &lt;strong&gt;fallisce con script SQL complessi&lt;/strong&gt; che contengono:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CREATE EXTENSION&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ALTER OWNER&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SET ROLE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;operazioni su schemi di sistema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 In questi casi &lt;code&gt;psql&lt;/code&gt; è lo strumento giusto.&lt;/p&gt;


&lt;h2&gt;
  
  
  Note operative – Comandi PostgreSQL di uso comune
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Creare un database
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;NomeDB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Creare una copia da un database esistente
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;testCopia&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;TEMPLATE&lt;/span&gt; &lt;span class="s1"&gt;'NomeDB'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Assegnare tutti i permessi a un utente
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;NomeDB&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="k"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Collegarsi a un database con un utente specifico
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-U&lt;/span&gt; admin &lt;span class="nt"&gt;-d&lt;/span&gt; NomeDB &lt;span class="nt"&gt;-h&lt;/span&gt; localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Eliminare un database
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgresql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost
DROP DATABASE database_da_eliminare WITH &lt;span class="o"&gt;(&lt;/span&gt;FORCE&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Backup con &lt;code&gt;pg_dump&lt;/code&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Creare un dump SQL
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_dump &lt;span class="nt"&gt;-f&lt;/span&gt; /tmp/nome_database_dump.sql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-W&lt;/span&gt; nome_database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Significato opzioni:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; → file di output&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-U postgres&lt;/code&gt; → utente DB&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-W&lt;/code&gt; → richiede password&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nome_database&lt;/code&gt; → nome database&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Evitare la richiesta password (automazioni)
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Metodo consigliato: &lt;code&gt;.pgpass&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;File &lt;code&gt;~/.pgpass&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hostname:port:database:username:password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permessi obbligatori:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.pgpass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Metodo rapido (meno sicuro)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PGPASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Ripristino di un database PostgreSQL: scegliere il comando giusto
&lt;/h2&gt;

&lt;p&gt;Il comando da usare per il ripristino &lt;strong&gt;dipende dal formato del backup&lt;/strong&gt;, ovvero da &lt;strong&gt;come è stato creato con &lt;code&gt;pg_dump&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;È un aspetto fondamentale: usare lo strumento sbagliato porta a errori o a ripristini incompleti.&lt;/p&gt;




&lt;h3&gt;
  
  
  1️⃣ Ripristino da file SQL (Plain Text)
&lt;/h3&gt;

&lt;p&gt;Se il backup è stato creato &lt;strong&gt;senza opzioni di formato&lt;/strong&gt; (output leggibile, &lt;code&gt;.sql&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_dump nome_database &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; backup.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;oppure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_dump &lt;span class="nt"&gt;-f&lt;/span&gt; /tmp/pnd_dump.sql nome_database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;il ripristino va fatto &lt;strong&gt;con &lt;code&gt;psql&lt;/code&gt;&lt;/strong&gt;, che esegue sequenzialmente le istruzioni SQL contenute nel file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-d&lt;/span&gt; nome_database &lt;span class="nt"&gt;-f&lt;/span&gt; /tmp/nome_database_dump.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note importanti:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Il database di destinazione &lt;strong&gt;deve già esistere&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Il file è leggibile e modificabile&lt;/li&gt;
&lt;li&gt;Su database molto grandi può essere più lento&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2️⃣ Ripristino da file Custom o Directory (&lt;code&gt;.dump&lt;/code&gt;, &lt;code&gt;.bak&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Se il backup è stato creato con:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_dump &lt;span class="nt"&gt;-Fc&lt;/span&gt; nome_database &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; backup.dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;oppure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_dump &lt;span class="nt"&gt;-Fd&lt;/span&gt; nome_database &lt;span class="nt"&gt;-f&lt;/span&gt; backup_dir
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;si tratta di un &lt;strong&gt;formato binario/speciale&lt;/strong&gt;, che &lt;strong&gt;non può essere eseguito con &lt;code&gt;psql&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In questo caso va usato &lt;strong&gt;&lt;code&gt;pg_restore&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_restore &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-d&lt;/span&gt; nome_database &lt;span class="nt"&gt;-v&lt;/span&gt; backup.dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Opzioni utili:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-v&lt;/code&gt; → modalità verbose&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--clean&lt;/code&gt; → elimina gli oggetti prima di ricrearli&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--if-exists&lt;/code&gt; → evita errori se gli oggetti non esistono&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Ripristino in parallelo (solo con &lt;code&gt;pg_restore&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Uno dei grandi vantaggi dei formati custom o directory è la possibilità di usare &lt;strong&gt;più core CPU&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_restore &lt;span class="nt"&gt;-j&lt;/span&gt; 4 &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-d&lt;/span&gt; nome_database backup.dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Ideale per database grandi in ambienti server.&lt;/p&gt;




&lt;h3&gt;
  
  
  Tabella rapida di riferimento
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Formato backup&lt;/th&gt;
&lt;th&gt;Strumento&lt;/th&gt;
&lt;th&gt;Quando usarlo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;.sql&lt;/code&gt; (plain text)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;psql&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Backup leggibile, semplice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;.dump&lt;/code&gt; (custom)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pg_restore&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Backup compresso, selettivo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;directory&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pg_restore&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ripristino veloce e parallelo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Nota operativa importante
&lt;/h3&gt;

&lt;p&gt;Se il database di destinazione è &lt;strong&gt;già in uso&lt;/strong&gt;, il ripristino può fallire per:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;connessioni attive&lt;/li&gt;
&lt;li&gt;oggetti già esistenti&lt;/li&gt;
&lt;li&gt;lock sulle tabelle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In questi casi è consigliabile:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ripristinare su un database vuoto&lt;/li&gt;
&lt;li&gt;oppure usare &lt;code&gt;--clean&lt;/code&gt; con attenzione&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusione
&lt;/h2&gt;

&lt;p&gt;In ambienti AWS con PostgreSQL in subnet private:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;non si espone mai il DB su Internet&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;il jump host è la chiave&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;psql&lt;/code&gt; è lo strumento più affidabile&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;i permessi contano più della GUI&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il &lt;strong&gt;tunnel SSH + &lt;code&gt;psql&lt;/code&gt;&lt;/strong&gt; resta la soluzione più solida, ripetibile e sicura per ripristinare database PostgreSQL in infrastrutture cloud ben progettate.&lt;/p&gt;




</description>
      <category>postgressql</category>
      <category>linux</category>
    </item>
    <item>
      <title>Inizializzare GIT e configurare autenticazione SSH GitHub</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Thu, 08 May 2025 08:54:46 +0000</pubDate>
      <link>https://dev.to/minnogit/inizializzare-git-4pfd</link>
      <guid>https://dev.to/minnogit/inizializzare-git-4pfd</guid>
      <description>&lt;p&gt;git --version&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global color.ui true
git config --global user.name 'Mario Rossi'
git config --global user.email emailAccount

git config --global core.editor nano
O questo per usare vscode:
git config --global core.editor "code --wait"

git config --global gui.editor gedit
git config --global init.defaultBranch main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se non si mette &lt;code&gt;--global&lt;/code&gt; la configurazione sarà relativa al repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent" rel="noopener noreferrer"&gt;Creare chiave ssh&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -t ed25519 -C "your_email@example.com"
cat ~/.ssh/id_ed25519_sk.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aggiungere al profilo &lt;a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account" rel="noopener noreferrer"&gt;Github&lt;/a&gt; la chiave pubblica.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository" rel="noopener noreferrer"&gt;Clonare il repository con ssh&lt;/a&gt;&lt;br&gt;
Ad es.: &lt;code&gt;git clone git@github.com:organizzazione/progetto.git&lt;/code&gt;&lt;br&gt;
Si può fare anche da &lt;a href="https://code.visualstudio.com/docs/sourcecontrol/github" rel="noopener noreferrer"&gt;VSCode&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Se si ottiene errore &lt;code&gt;Permission denied (publickey)&lt;/code&gt; vuol dire che il comando git non trova o non può usare la chiave SSH per parlare con GitHub.&lt;br&gt;
Mi è successo in ambiente di sviluppo Dev Container con Docker Rootless in cui il Dev Container cerca di passare le chiavi dall'host al container.&lt;br&gt;
Per risolvere, verificare se l'agente SSH è vivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$SSH_AUTH_SOCK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se l'output è vuoto: VS Code non sta passando l'agente SSH al container.&lt;br&gt;
Se vedi un percorso (es. /tmp/vscode-ssh-auth...): L'agente è passato, ma dobbiamo vedere se possiamo usarlo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-add &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se dice "The agent has no identities": L'agente è collegato ma "vuoto" (devi fare &lt;code&gt;ssh-add&lt;/code&gt; sul tuo host Linux).&lt;/p&gt;

&lt;p&gt;Verificare la connessione con &lt;code&gt;ssh -vT git@github.com&lt;/code&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Elenco in Conky di applicazioni con l'uso della swap</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Thu, 20 Apr 2023 15:30:00 +0000</pubDate>
      <link>https://dev.to/minnogit/elenco-in-conky-di-applicazioni-con-luso-della-swap-5af7</link>
      <guid>https://dev.to/minnogit/elenco-in-conky-di-applicazioni-con-luso-della-swap-5af7</guid>
      <description>&lt;p&gt;In continuazione del precedente post, adesso vediamo come stampare in Conky un elenco di programmi con la relativa quantità di swap usata.&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;unioneTest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; /proc/&lt;span class="k"&gt;*&lt;/span&gt;/status&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/^(Name:)/ {awk_name=$2} /^(VmSwap:)/ {awk_vmswap=$2" "$3} /^(Pid:)/ {awk_pid=$2} END { if (awk_vmswap &amp;amp;&amp;amp; substr(awk_vmswap,1,1) != '&lt;/span&gt;0&lt;span class="s1"&gt;' ) print awk_name" "awk_pid" "awk_vmswap}'&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$test&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;unioneTest+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$test&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
  fi
done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A differenza del comando precedente, alla fine dell'analisi awk di ogni file, viene verificato se la variabile &lt;em&gt;awk_vmswap&lt;/em&gt; 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 &lt;em&gt;test&lt;/em&gt;.&lt;br&gt;
Se la variabile &lt;em&gt;test&lt;/em&gt; non è vuota, viene aggiunto alla variabile &lt;em&gt;unioneTest&lt;/em&gt; e viene inserito un carattere di nuova linea ("\n") per separare i record.&lt;br&gt;
Alla fine, &lt;em&gt;$unioneTest&lt;/em&gt; conterrà l'elenco dei processi che usano la swap.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;dati&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$unioneTest&lt;/span&gt;
&lt;span class="nb"&gt;declare&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; somma

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; linea&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$linea&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;valore&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$linea&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="nt"&gt;-f3&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;((&lt;/span&gt;somma[&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; +&lt;span class="o"&gt;=&lt;/span&gt; valore&lt;span class="o"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$unioneTest&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il ciclo &lt;em&gt;while&lt;/em&gt; viene alimentato con un &lt;a href="https://tldp.org/LDP/abs/html/x17837.html" rel="noopener noreferrer"&gt;here-string&lt;/a&gt; (&amp;lt;&amp;lt;&amp;lt;) che contiene l'output di un comando &lt;em&gt;echo -e&lt;/em&gt; che converte una stringa contenente i dati da elaborare.&lt;/p&gt;

&lt;p&gt;Infine, stampiamo l'elenco dall'array &lt;em&gt;somma&lt;/em&gt; 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.&lt;br&gt;
La lunghezza delle righe, verrà specificata da un parametro dello script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;elenco&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;nome &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;!somma[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;somma&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; kB&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;nrSpacesToAdd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;expr&lt;/span&gt; &lt;span class="nv"&gt;$spaces&lt;/span&gt; - &lt;span class="k"&gt;${#&lt;/span&gt;&lt;span class="nv"&gt;tmp&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    elenco+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%*s'&lt;/span&gt; &lt;span class="nv"&gt;$nrSpacesToAdd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;somma&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; kB&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;done
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$elenco&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; 2 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;code&gt;(printf '%*s' $nrSpacesToAdd)&lt;/code&gt; viene utilizzato per generare una stringa di spazi della lunghezza &lt;em&gt;$nrSpacesToAdd&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Questo è lo script completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$# &lt;/span&gt;&lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Specificare la lunghezza delle stringhe"&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Lunghezza voluta delle stringhe&lt;/span&gt;
&lt;span class="nv"&gt;spaces&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;

&lt;span class="nv"&gt;unioneTest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; /proc/&lt;span class="k"&gt;*&lt;/span&gt;/status&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/^(Name:)/ {awk_name=$2} /^(VmSwap:)/ {awk_vmswap=$2" "$3} /^(Pid:)/ {awk_pid=$2} END { if (awk_vmswap &amp;amp;&amp;amp; substr(awk_vmswap,1,1) != '&lt;/span&gt;0&lt;span class="s1"&gt;' ) print awk_name" "awk_pid" "awk_vmswap}'&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$test&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;unioneTest+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$test&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
  fi
done

if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$unioneTest&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;dati&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$unioneTest&lt;/span&gt;
  &lt;span class="nb"&gt;declare&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; somma

  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; linea&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;nome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$linea&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;valore&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$linea&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &lt;span class="nt"&gt;-f3&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;((&lt;/span&gt;somma[&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; +&lt;span class="o"&gt;=&lt;/span&gt; valore&lt;span class="o"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;done&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$unioneTest&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="nv"&gt;elenco&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;nome &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;!somma[@]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;somma&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; kB&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;nrSpacesToAdd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;expr&lt;/span&gt; &lt;span class="nv"&gt;$spaces&lt;/span&gt; - &lt;span class="k"&gt;${#&lt;/span&gt;&lt;span class="nv"&gt;tmp&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    elenco+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%*s'&lt;/span&gt; &lt;span class="nv"&gt;$nrSpacesToAdd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;somma&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$nome&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; kB&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;done
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$elenco&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; 2 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esempio di output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;./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
&lt;span class="o"&gt;(&lt;/span&gt;sd-pam&lt;span class="o"&gt;)&lt;/span&gt;                          64 kB
containerd                        60 kB
spotify                           52 kB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Per usare il comando in Conky, ho aggiunto al file di configurazione .conkyrc le seguenti linee nella sezione conky.text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
$hr
${color grey}Name                          Swap used
${color lightgrey}${execi 30 ~/swapUsed.sh 41 | head -n 10}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Qui il file .conkyrc completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- 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}
]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8gmaiepta7kxydr6cqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8gmaiepta7kxydr6cqq.png" alt=" " width="292" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Gestire la cache di npm e considerazioni per Docker</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Mon, 17 Apr 2023 09:06:54 +0000</pubDate>
      <link>https://dev.to/minnogit/gestire-la-cache-di-npm-e-considerazioni-per-docker-8po</link>
      <guid>https://dev.to/minnogit/gestire-la-cache-di-npm-e-considerazioni-per-docker-8po</guid>
      <description>&lt;p&gt;Quando si richiede di installare un pacchetto npm, questo viene scaricato da internet e salvato nella cartella di cache, se non è già presente, e poi installato nell'applicazione che lo richiede.&lt;br&gt;
Dalla versione 5 di npm, la gestione della cache è &lt;em&gt;self-healing&lt;/em&gt; per cui dovrebbe riconoscere eventuali pacchetti incompleti, danneggiati o obsoleti e, in tal caso, scaricarli nuovamente cercando anche di risolvere automaticamente le dipendenze nel modo migliore.&lt;br&gt;
Tuttavia in alcuni casi, anche per risolvere problemi di installazione, è utile pulire la cache di npm con il comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nt"&gt;--global&lt;/span&gt; cache verify
Cache verified and compressed &lt;span class="o"&gt;(&lt;/span&gt;~/git/.npm/_cacache&lt;span class="o"&gt;)&lt;/span&gt;
Content verified: 9127 &lt;span class="o"&gt;(&lt;/span&gt;1525196266 bytes&lt;span class="o"&gt;)&lt;/span&gt;
Content garbage-collected: 3491 &lt;span class="o"&gt;(&lt;/span&gt;5398705346 bytes&lt;span class="o"&gt;)&lt;/span&gt;
Index entries: 9129
Finished &lt;span class="k"&gt;in &lt;/span&gt;34.248s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La cartella della cache normalmente è &lt;code&gt;~/.npm&lt;/code&gt; (nell'es. sopra è &lt;code&gt;~/git/.npm&lt;/code&gt;) ma è possibile spostarla.&lt;br&gt;
Possono esserci diversi motivi per cui si potrebbe voler controllare il percorso della cache:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;la cartella può arrivare a occupare uno spazio considerevole e si potrebbe volerla spostare.&lt;/li&gt;
&lt;li&gt;si vuole usare una cartella di cache condivisa tra più host per velocizzare le installazioni.&lt;/li&gt;
&lt;li&gt;si vuole una cache condivisa tra gli utenti della stessa macchina.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Il comando per spostare la cartella di cache è:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm config &lt;span class="nb"&gt;set &lt;/span&gt;cache nuovaCartella &lt;span class="nt"&gt;--global&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Al posto di modificare la configurazione del file di configurazione di npm, è anche possibile impostare il percorso della cache in una variabile di ambiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;npm_config_cache&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/path/to/cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dopo aver spostato la cache, lanciare il comando di verifica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nt"&gt;--global&lt;/span&gt; cache verify&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E' possibile vedere la configurazione attuale con il comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm config list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il comando di verifica non cancella pacchetti scaricati ma non più usati, perciò si potrebbe voler cancellare tutta la cache con il comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm cache clean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Considerazioni per Docker
&lt;/h2&gt;

&lt;p&gt;Se stiamo usando Docker, è possibile impostare la cartella della cache con:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;npm_config_cache&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/path/to/cache mydockerimage:tag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In questo modo, il comando &lt;code&gt;docker run&lt;/code&gt; consente di eseguire un container Docker configurato per utilizzare una specifica directory per la cache dei pacchetti npm.&lt;br&gt;
Controllando dove i pacchetti vengono salvati, si può condividere la cache tra diversi container o host, ad esempio per ridurre il tempo di download dei pacchetti npm o per evitare di scaricare i pacchetti più volte.&lt;br&gt;
Inoltre, ci permette di usare la stessa cartella di cache anche quando si avvia il container con un utente diverso da quello attuale (ogni utente ha la sua cartella di cache).&lt;/p&gt;

</description>
      <category>npm</category>
      <category>docker</category>
      <category>linux</category>
    </item>
    <item>
      <title>Dividere il monitor in 4 terminali con Terminator</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Thu, 13 Apr 2023 10:56:31 +0000</pubDate>
      <link>https://dev.to/minnogit/dividere-il-monitor-in-4-terminali-con-terminator-51ko</link>
      <guid>https://dev.to/minnogit/dividere-il-monitor-in-4-terminali-con-terminator-51ko</guid>
      <description>&lt;p&gt;Una delle prime cose che faccio quando la mattina entro nel pc al lavoro, è aprire alcuni terminali.&lt;/p&gt;

&lt;p&gt;Di solito uso &lt;a href="https://gnome-terminator.org/" rel="noopener noreferrer"&gt;Terminator&lt;/a&gt; che è un emulatore di terminale per Linux che consente di aprire e gestire più finestre di terminale all'interno di una sola finestra.&lt;br&gt;
Ha diverse caratteristiche interessanti, anche se la sua configurazione non è molto intuitiva per certi aspetti.&lt;/p&gt;

&lt;p&gt;La suddivisione in 4 terminali della finestra di Terminator è definita come un &lt;strong&gt;layout&lt;/strong&gt; nel suo file di configurazione.&lt;br&gt;
Ho quindi aggiunto un layout personalizzato &lt;em&gt;server&lt;/em&gt; dalla finestra delle preferenze.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fju7fgow3n4a0226hvyq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fju7fgow3n4a0226hvyq1.png" alt="Terminator" width="800" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si può anche modificare direttamente il file di configurazione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;nano ~/.config/terminator/config

&lt;span class="o"&gt;[&lt;/span&gt;global_config]
  enabled_plugins &lt;span class="o"&gt;=&lt;/span&gt; CustomCommandsMenu, APTURLHandler
  suppress_multiple_term_dialog &lt;span class="o"&gt;=&lt;/span&gt; True
&lt;span class="o"&gt;[&lt;/span&gt;keybindings]
&lt;span class="o"&gt;[&lt;/span&gt;profiles]
  &lt;span class="o"&gt;[[&lt;/span&gt;default]]
    background_darkness &lt;span class="o"&gt;=&lt;/span&gt; 0.85
    font &lt;span class="o"&gt;=&lt;/span&gt; Monospace 9
    scrollback_lines &lt;span class="o"&gt;=&lt;/span&gt; 2000
    use_system_font &lt;span class="o"&gt;=&lt;/span&gt; False
&lt;span class="o"&gt;[&lt;/span&gt;layouts]
  &lt;span class="o"&gt;[[&lt;/span&gt;default]]
    &lt;span class="o"&gt;[[[&lt;/span&gt;child1]]]
      parent &lt;span class="o"&gt;=&lt;/span&gt; window0
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; Terminal
      &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="o"&gt;[[[&lt;/span&gt;window0]]]
      parent &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; Window
  &lt;span class="o"&gt;[[&lt;/span&gt;servers]]
    &lt;span class="o"&gt;[[[&lt;/span&gt;child0]]]
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; Window
      parent &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
      order &lt;span class="o"&gt;=&lt;/span&gt; 0
      position &lt;span class="o"&gt;=&lt;/span&gt; 0:0
      maximised &lt;span class="o"&gt;=&lt;/span&gt; True
      fullscreen &lt;span class="o"&gt;=&lt;/span&gt; False
      size &lt;span class="o"&gt;=&lt;/span&gt; 1920, 995
      title &lt;span class="o"&gt;=&lt;/span&gt; admin@node01: ~
      last_active_term &lt;span class="o"&gt;=&lt;/span&gt; 428ce1c8-9aed-4acf-a481-45a18c5f54a9
      last_active_window &lt;span class="o"&gt;=&lt;/span&gt; True
    &lt;span class="o"&gt;[[[&lt;/span&gt;child1]]]
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; HPaned
      parent &lt;span class="o"&gt;=&lt;/span&gt; child0
      order &lt;span class="o"&gt;=&lt;/span&gt; 0
      position &lt;span class="o"&gt;=&lt;/span&gt; 958
      ratio &lt;span class="o"&gt;=&lt;/span&gt; 0.5002610966057441
    &lt;span class="o"&gt;[[[&lt;/span&gt;child2]]]
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; VPaned
      parent &lt;span class="o"&gt;=&lt;/span&gt; child1
      order &lt;span class="o"&gt;=&lt;/span&gt; 0
      position &lt;span class="o"&gt;=&lt;/span&gt; 495
      ratio &lt;span class="o"&gt;=&lt;/span&gt; 0.5
    &lt;span class="o"&gt;[[[&lt;/span&gt;terminal3]]]
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; Terminal
      parent &lt;span class="o"&gt;=&lt;/span&gt; child2
      order &lt;span class="o"&gt;=&lt;/span&gt; 0
      profile &lt;span class="o"&gt;=&lt;/span&gt; default
      uuid &lt;span class="o"&gt;=&lt;/span&gt; a1b21c6d-82fa-4907-9b35-838b3743bb62
      &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="o"&gt;[[[&lt;/span&gt;terminal4]]]
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; Terminal
      parent &lt;span class="o"&gt;=&lt;/span&gt; child2
      order &lt;span class="o"&gt;=&lt;/span&gt; 1
      profile &lt;span class="o"&gt;=&lt;/span&gt; default
      uuid &lt;span class="o"&gt;=&lt;/span&gt; 9a8f88b6-22e6-49f4-865f-d100a84fa56e
      &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="o"&gt;[[[&lt;/span&gt;child5]]]
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; VPaned
      parent &lt;span class="o"&gt;=&lt;/span&gt; child1
      order &lt;span class="o"&gt;=&lt;/span&gt; 1
      position &lt;span class="o"&gt;=&lt;/span&gt; 496
      ratio &lt;span class="o"&gt;=&lt;/span&gt; 0.5
    &lt;span class="o"&gt;[[[&lt;/span&gt;terminal6]]]
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; Terminal
      parent &lt;span class="o"&gt;=&lt;/span&gt; child5
      order &lt;span class="o"&gt;=&lt;/span&gt; 0
      profile &lt;span class="o"&gt;=&lt;/span&gt; default
      uuid &lt;span class="o"&gt;=&lt;/span&gt; 716efc36-9385-4b79-898f-a437165c439b
      &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="o"&gt;[[[&lt;/span&gt;terminal7]]]
      &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; Terminal
      parent &lt;span class="o"&gt;=&lt;/span&gt; child5
      order &lt;span class="o"&gt;=&lt;/span&gt; 1
      profile &lt;span class="o"&gt;=&lt;/span&gt; default
      uuid &lt;span class="o"&gt;=&lt;/span&gt; 428ce1c8-9aed-4acf-a481-45a18c5f54a9
      &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;plugins]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adesso è possibile avviare Terminator specificando di usare il layout &lt;em&gt;server&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terminator &lt;span class="nt"&gt;--layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;servers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Infine, ho creato un launcher apposito per gnome-shell con &lt;a href="https://github.com/bluesabre/menulibre" rel="noopener noreferrer"&gt;MenuLibre&lt;/a&gt; per eseguire il comando sopra.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwclsfiso0zx6x65xs07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwclsfiso0zx6x65xs07.png" alt="MenuLibre" width="712" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>linux</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Stampare un elenco dei processi ordinato per la quantità di swap che usano</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Wed, 15 Mar 2023 22:21:24 +0000</pubDate>
      <link>https://dev.to/minnogit/stampare-un-elenco-dei-processi-ordinato-per-la-quantita-di-swap-che-usano-lmo</link>
      <guid>https://dev.to/minnogit/stampare-un-elenco-dei-processi-ordinato-per-la-quantita-di-swap-che-usano-lmo</guid>
      <description>&lt;p&gt;Cercando su internet possiamo trovare questo comando per stampare l'elenco dei processi ordinato per uso del file di Swap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; /proc/&lt;span class="k"&gt;*&lt;/span&gt;/status &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/VmSwap|Name/{printf $2 " " $3}END{ print ""}'&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; 2 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; | less
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Poiché per me è abbastanza magico, ho cercato di capire come funziona:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;for file in /proc/*/status&lt;/code&gt; - 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:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/6377/status
Name:   gnome-software
Umask:  0022
State:  S &lt;span class="o"&gt;(&lt;/span&gt;sleeping&lt;span class="o"&gt;)&lt;/span&gt;
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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done&lt;/code&gt; - 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.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sort -k 2 -n -r&lt;/code&gt; - Ordina l'output in base al secondo campo (-k 2) in ordine numerico (-n) in ordine inverso (-r).&lt;br&gt;
Significa che la quantità di swap usata dai processi è ordinata dal più grande al più piccolo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;less&lt;/code&gt; - Visualizzare l'output paginato nel terminale.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Es. di output del comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; /proc/&lt;span class="k"&gt;*&lt;/span&gt;/status &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/VmSwap|Name/{printf $2 " " $3}END{ print ""}'&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; 2 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; | less
gnome-software 218708 kB
mariadbd 155576 kB
code 147548 kB
code 134844 kB
firefox 111212 kB
WebExtensions 71236 kB
java 70472 kB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se vogliamo aggiungere la stampa del Pid possiamo modificare il comando in questo modo:&lt;/p&gt;

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

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

&lt;p&gt;Es. di output del comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; /proc/&lt;span class="k"&gt;*&lt;/span&gt;/status &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/^(VmSwap:|Name:|Pid:)/ {printf $2 " " $3}END{ print ""}'&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-k&lt;/span&gt; 3 &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; | less
gnome-software 6377 218708 kB
mariadbd 46522 155576 kB
code 41703 147548 kB
code 40429 134844 kB
firefox 8840 111212 kB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>linux</category>
      <category>bash</category>
      <category>italian</category>
    </item>
    <item>
      <title>Modificare allarme di spazio libero per un disco in Netdata</title>
      <dc:creator>minnogit</dc:creator>
      <pubDate>Mon, 13 Mar 2023 14:01:40 +0000</pubDate>
      <link>https://dev.to/minnogit/modificare-allarme-di-spazio-libero-per-un-disco-in-netdata-4k54</link>
      <guid>https://dev.to/minnogit/modificare-allarme-di-spazio-libero-per-un-disco-in-netdata-4k54</guid>
      <description>&lt;p&gt;Dall'interfaccia web di Netdata, in alto a destra, si vedono gli allarmi e, nei dettagli di ognuno, sono specificati i relativi file di configurazione.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbiaog3ghxk1qgfgyz7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbiaog3ghxk1qgfgyz7f.png" alt=" " width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ad es., dai dettagli sopra si vede che l'allarme è configurato nel file &lt;em&gt;/opt/netdata/usr/lib/netdata/conf.d/health.d/disks.conf&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Se vogliamo che l'allarme per il disco &lt;em&gt;/mnt/disco_utenti&lt;/em&gt; abbia regole diverse rispetto a quelle per gli altri dischi, possiamo modificare la configurazione così:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /opt/netdata/usr/lib/netdata/conf.d/health.d/disks.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Escludo il disco &lt;em&gt;/mnt/disco_utenti&lt;/em&gt; dalla configurazione attuale modificando la lista &lt;em&gt;families&lt;/em&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# -----------------------------------------------------------------------------
# low disk space

# checking the latest collected values
# raise an alarm if the disk is low on
# available disk space

 template: disk_space_usage
       on: disk.space
    class: Utilization
     type: System
component: Disk
       os: linux freebsd
    hosts: *
 families: !/mnt/disco_utenti !/mnt/disco_utenti !/dev !/dev/* !/run !/run/* *
     calc: $used * 100 / ($avail + $used)
    units: %
    every: 1m
     warn: $this &amp;gt; (($status &amp;gt;= $WARNING ) ? (80) : (90))
     crit: $this &amp;gt; (($status == $CRITICAL) ? (90) : (98))
    delay: up 1m down 15m multiplier 1.5 max 1h
     info: disk ${label:mount_point} space utilization
       to: sysadmin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Aggiungo alla configurazione una nuova sezione per l'allarme del disco &lt;em&gt;/mnt/disco_utenti&lt;/em&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# -----------------------------------------------------------------------------
# low disk space

# checking the latest collected values
# raise an alarm if the disk is low on
# available disk space

 template: disk_space_usage
       on: disk.space
    class: Utilization
     type: System
component: Disk
       os: linux freebsd
    hosts: *
 families: /mnt/disco_utenti
     calc: $used * 100 / ($avail + $used)
    units: %
    every: 10m
     warn: $this &amp;gt; (($status &amp;gt;= $WARNING ) ? (96) : (98))
     crit: $this &amp;gt; (($status == $CRITICAL) ? (98) : (99))
    delay: up 1m down 15m multiplier 1.5 max 1h
     info: disk ${label:mount_point} space utilization
       to: sysadmin

 template: disk_inode_usage
      on: disk.inodes
    class: Utilization
     type: System
component: Disk
       os: linux freebsd
    hosts: *
 families: !/dev !/dev/* !/run !/run/* *
     calc: $used * 100 / ($avail + $used)
    units: %
    every: 1m
     warn: $this &amp;gt; (($status &amp;gt;= $WARNING)  ? (80) : (90))
     crit: $this &amp;gt; (($status == $CRITICAL) ? (90) : (98))
    delay: up 1m down 15m multiplier 1.5 max 1h
     info: disk ${label:mount_point} inode utilization
       to: sysadmin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Riavviare Netdata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl restart netdata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>linux</category>
      <category>monitoring</category>
      <category>italian</category>
      <category>netdata</category>
    </item>
  </channel>
</rss>
