Linux Tutorial – Puntata 26
di jolek78
Care/i fruitrici e fruitori del blog, in questi post – ogni domenica mattina – si parlerà del sistema operativo GNU/Linux e degli strumenti per utilizzarlo al massimo delle potenzialità. Cercheremo di spiegare come funziona, cosa è il kernel, come costruirsi una vpn, come settare un firewall e giocare col terminale, usare adb e altro. Se il capitalismo della sorveglianza ci vuole passivi consumatori-consumatrici di servizi noi si risponde con un po’ di “cultura informatica” e un MARAMEO (quasi affettuoso). Buona lettura!
Due notti fa mentre rovistavo fra scatoli e scatoloni alla ricerca di un adattatore slimport usb-hdmi, ho ritrovato, in un piccolo anfratto impolverato, un vecchio router con openwrt installato, ancora attivo e ancora funzionante. Openwrt, per la cronaca, è una piattaforma opensource basata su linux, molto flessibile, e progettata espressamente per router. Data di produzione: circa quindici anni fa. Diamine, ma da quanto tempo vedo sui miei schermi comandi, terminali e pinguini? Molto, forse troppo. Sia come sia, questo mia ha ricordato che il primo incontro con il comando che vedremo in questo tutorial, awk, fu davvero tanti anni fa quando volevo fare vedere a un amico come si poteva esportare una sola colonna di excel in un semplice file di testo. awk in realtà, più che un comando, è un linguaggio di scripting, e quindi per parlarne, bisognerebbe entrare molto nei dettagli. In questa puntata pero’, come nostro solito, ci terremo sui fondamentali. È domenica, non voglio farvi venire il mal di testa. Bentornati!
– man
bottega@bottegadelbarbieri ~ man awk |head -n 18 MAWK(1) USER COMMANDS MAWK(1) NAME mawk - pattern scanning and text processing language SYNOPSIS mawk [-W option] [-F value] [-v var=value] [--] 'program text' [file ...] mawk [-W option] [-F value] [-v var=value] [-f program-file] [--] [file ...] DESCRIPTION mawk is an interpreter for the AWK Programming Language. The AWK language is useful for manipulation of data files, text retrieval and processing, and for prototyping and experimenting with algorithms. mawk is a new awk meaning it implements the AWK language as defined in Aho, Kernighan and Weinberger, The AWK Programming Language, Addison-Wesley Publishing, 1988 (hereafter referred to as the AWK book.) mawk conforms to the POSIX 1003.2 (draft 11.3) definition of the AWK language which contains a few features not described in the AWK book, and mawk provides a small number of extensions. An AWK program is a sequence of pattern {action} pairs and function definitions. Short programs are entered on the command line usually enclosed in ' ' to avoid shell interpretation. Longer programs can be read in from a file with the -f option. Data input is read from the list of files on the command line or from standard input when the list is empty. The input is broken into records as determined by the record separator variable, RS. Initially, RS = “\n” and records are synonymous with lines. Each record is compared against each pattern and if it matches, the program text for {action} is executed.
Per questo tutorial utilizzeremo due esempi. Il primo è un file che abbiamo conosciuto nelle prime puntate del tutorial, ed è il /etc/passwd, ovvero dove sono conservate, in maniera criptata, tutte la password e le informazioni appartenenti agli utenti del sistema. Il secondo e’ ovviamente la arcinota novella di Coleridge “the rhyme of the ancient mariner” che abbiamo stra utilizzato in queste ultime puntate. Un giorno Coleridge ci citerà per danni, ne son convinto…
bottega@bottegadelbarbieri ~ cat the-rhyme-of-the-ancient-mariner.txt |head -n 20 PART THE FIRST. It is an ancient Mariner, And he stoppeth one of three. "By thy long grey beard and glittering eye, Now wherefore stopp'st thou me? "The Bridegroom's doors are opened wide, And I am next of kin; The guests are met, the feast is set: May'st hear the merry din." He holds him with his skinny hand, "There was a ship," quoth he. "Hold off! unhand me, grey-beard loon!" Eftsoons his hand dropt he. He holds him with his glittering eye-- The Wedding-Guest stood still, And listens like a three years child: bottega@bottegadelbarbieri ~ cat /etc/passwd |head -n 20 root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
– select colum || $
Dunque, partiamo dalla novella di Coleridge e proviamo a selezionare la prima colonna a sinistra. Il gioco e’ inserire il numero della colonna dopo il simbolo del dollaro $. Non è chiaro? Vediamo cosa intendo.
bottega@bottegadelbarbieri ~ cat the-rhyme-of-the-ancient-mariner.txt |head -n 20 |awk '{print $1}' PART It And "By Now "The And The May'st He "There "Hold Eftsoons He The And
Cosa succede se proviamo a fare la stessa operazione su /etc/passwd?
bottega@bottegadelbarbieri ~ cat /etc/passwd |head -n 20 |awk '{print $1}' root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-network:x:100:102:systemd systemd-resolve:x:101:103:systemd
Cosa è successo? Banalmente fra la prima e la seconda colonna non c’era una separazione delimitata da uno spazio, ma da un simbolo, il :. Dunque aggiungiamo fra awk e le parentesi graffe un simbolo:
bottega@bottegadelbarbieri ~ cat /etc/passwd |head -n 20 |awk -F: '{print $1}' root daemon bin sys sync games man lp mail news uucp proxy www-data backup list irc gnats nobody systemd-network systemd-resolve
– modify word || $n=word
Ora invece proviamo a modificare, a schermo, la prima parola che ci viene visualizzata sulla prima, sulla seconda e sulla terza colonna col simbolo =. In questo modo introdurremo un altro parametro: con awk possiamo visualizzare più colonne allo stesso momento separate dal simbolo , :
bottega@bottegadelbarbieri ~ cat /etc/passwd |head -n 20 |awk -F: '{print $1="pippo", $2="pluto", $3="paperino"}' pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino pippo pluto paperino
Ma com’era l’originale?
bottega@bottegadelbarbieri ~ cat /etc/passwd |head -n 20 |awk -F: '{print $1, $2, $3}' root x 0 daemon x 1 bin x 2 sys x 3 sync x 4 games x 5 man x 6 lp x 7 mail x 8 news x 9 uucp x 10 proxy x 13 www-data x 33 backup x 34 list x 38 irc x 39 gnats x 41 nobody x 65534 systemd-network x 100 systemd-resolve x 101
Ok, dobbiamo aggiungere alla lista delle citazioni per danni anche Walt Disney. Ma non è colpa mia se in campo informatico si usano questi nomi fin dall’eta’ della pietra…
– quoting || q=’x’
Vediamo ora cosa succede se vogliamo aggiungere un simbolo all’inizio e alla fine di ogni parola apparenterete a una determinata colonna. Tipicamente, il simbolo sarà “ ma, per mostrare che la definizione è la stessa, utilizzeremo il simbolo ^ definito dalla variabile q:
bottega@bottegadelbarbieri ~ cat /etc/passwd |head -n 20 |awk -F: '{print q $1 q, q $2 q, q $3 q}' q='^' ^root^ ^x^ ^0^ ^daemon^ ^x^ ^1^ ^bin^ ^x^ ^2^ ^sys^ ^x^ ^3^ ^sync^ ^x^ ^4^ ^games^ ^x^ ^5^ ^man^ ^x^ ^6^ ^lp^ ^x^ ^7^ ^mail^ ^x^ ^8^ ^news^ ^x^ ^9^ ^uucp^ ^x^ ^10^ ^proxy^ ^x^ ^13^ ^www-data^ ^x^ ^33^ ^backup^ ^x^ ^34^ ^list^ ^x^ ^38^ ^irc^ ^x^ ^39^ ^gnats^ ^x^ ^41^ ^nobody^ ^x^ ^65534^ ^systemd-network^ ^x^ ^100^ ^systemd-resolve^ ^x^ ^101^
Se invece definiamo la variabile in un altro modo, ecco cosa succede:
bottega@bottegadelbarbieri ~ cat /etc/passwd |head -n 20 |awk -F: '{print q $1 d, q $2 d, q $3 d}' q='{' d='}' {root} {x} {0} {daemon} {x} {1} {bin} {x} {2} {sys} {x} {3} {sync} {x} {4} {games} {x} {5} {man} {x} {6} {lp} {x} {7} {mail} {x} {8} {news} {x} {9} {uucp} {x} {10} {proxy} {x} {13} {www-data} {x} {33} {backup} {x} {34} {list} {x} {38} {irc} {x} {39} {gnats} {x} {41} {nobody} {x} {65534} {systemd-network} {x} {100} {systemd-resolve} {x} {101}
Chiaro? Nel primo esempio abbiamo definito una sola variabile q prima e dopo la parola. Nel secondo esempio abbiamo definito due variabili differenti, q e d, prima e dopo la colonna. Straordinario vero? Ora che avete capito come funziona, e sapete dalle precedenti puntate che per esportare un file in un altro file possiamo utilizzare il simbolo >, o per aggiungere linee il simbolo >>, avrete sicuramente già capito che questo è uno dei metodi per creare contenuti all’interno di uno script in bash.
– split || ‘/../’
Torniamo ora alla novella di Coleridge. Come sappiamo e’ divisa in sette capitoli separati, nel nostro file, dalla parola “PART”
bottega@bottegadelbarbieri ~ cat the-rhyme-of-the-ancient-mariner.txt |grep PART PART THE FIRST. PART THE SECOND. PART THE THIRD. PART THE FOURTH. PART THE FIFTH. PART THE SIXTH. PART THE SEVENTH.
Facciamo la stessa operazione con awk:
bottega@bottegadelbarbieri ~ cat the-rhyme-of-the-ancient-mariner.txt |awk '/^PART/ {print $0}' PART THE FIRST. PART THE SECOND. PART THE THIRD. PART THE FOURTH. PART THE FIFTH. PART THE SIXTH. PART THE SEVENTH.
Facendo in questo modo si capirà meglio l’operazione che andremo a fare in seguito. In sostanza prima di {print} abbiamo banalmente fatto precedere la parola che volevamo selezionare nel nostro output delimitata fra due simboli /. Ma ora faremo qualcosa di diverso. Occhio:
bottega@bottegadelbarbieri ~ awk '/PART/{n++}{print > "the-rhyme" n ".txt"}' the-rhyme-of-the-ancient-mariner.txt bottega@bottegadelbarbieri ~ ls -lha the-rhyme{1..7}.txt -rw-rw-r-- 1 bottega bottega 3.1K Sep 4 18:36 the-rhyme1.txt -rw-rw-r-- 1 bottega bottega 2.2K Sep 4 18:36 the-rhyme2.txt -rw-rw-r-- 1 bottega bottega 3.1K Sep 4 18:36 the-rhyme3.txt -rw-rw-r-- 1 bottega bottega 2.5K Sep 4 18:36 the-rhyme4.txt -rw-rw-r-- 1 bottega bottega 4.4K Sep 4 18:36 the-rhyme5.txt -rw-rw-r-- 1 bottega bottega 3.8K Sep 4 18:36 the-rhyme6.txt -rw-rw-r-- 1 bottega bottega 4.1K Sep 4 18:36 the-rhyme7.txt
Cosa è successo? Quanti files abbiamo creato?
bottega@bottegadelbarbieri ~ ls -lha the-rhyme{1..7}.txt -rw-rw-r-- 1 bottega bottega 3.1K Sep 4 18:36 the-rhyme1.txt -rw-rw-r-- 1 bottega bottega 2.2K Sep 4 18:36 the-rhyme2.txt -rw-rw-r-- 1 bottega bottega 3.1K Sep 4 18:36 the-rhyme3.txt -rw-rw-r-- 1 bottega bottega 2.5K Sep 4 18:36 the-rhyme4.txt -rw-rw-r-- 1 bottega bottega 4.4K Sep 4 18:36 the-rhyme5.txt -rw-rw-r-- 1 bottega bottega 3.8K Sep 4 18:36 the-rhyme6.txt -rw-rw-r-- 1 bottega bottega 4.1K Sep 4 18:36 the-rhyme7.txt
Visualizziamo il terzo file giusto per vedere cosa abbiamo combinato:
bottega@bottegadelbarbieri ~ cat the-rhyme3.txt |head PART THE THIRD. There passed a weary time. Each throat Was parched, and glazed each eye. A weary time! a weary time! How glazed each weary eye, When looking westward, I beheld A something in the sky. At first it seemed a little speck,
Ed ecco il terzo capitolo della novella. Non ci credete? Confrontiamo il terzo capitolo riportato nel file intero, e il terzo capitolo nel file esportato. Se il risultato di diff sarà nullo, allora i due saranno identici. Provare per credere:
bottega@bottegadelbarbieri ~ wc -l the-rhyme3.txt 104 the-rhyme3.txt bottega@bottegadelbarbieri ~ cat the-rhyme-of-the-ancient-mariner.txt |grep -A104 "PART THE THIRD." > 3.txt bottega@bottegadelbarbieri ~ diff 3.txt the-rhyme3.txt bottega@bottegadelbarbieri ~
Abbiamo in buona sostanza diviso il file nei sette capitoli, utilizzando come delimitatore la parola “PART” e dicendo ad awk “fammi vedere quello che viene fra un PART e l’altro, in più esporta il contenuto e creami n files che comincino con un determinato nome”. Magic! Ovvio, awk non è solo questo ma è molto molto altro. E quindi… a voi i compiti per casa.
Alla prossima settimana!
jolek78
>> | Indice | << |
Puntata 25 | < > | Puntata 27 |
Il logo “Tux Linux” e’ stato realizzato e distribuito dall’artista deiby-ybied su Deviantart in licenza Creative Commons BY-NC-SA 3.0