Capitolo 1. Tutorial GNU/Linux

# Capitolo 1. Tutorial GNU/Linux

Penso che imparare un sistema informatico sia come imparare una lingua straniera. Anche se le guide e la documentazione sono utili, si deve fare pratica diretta. Per aiutare il lettore a iniziare dolcemente, ho elaborato alcuni punti base.

Il potente design di Debian GNU/Linux deriva dal sistema operativo Unix, cioè un sistema operativo multiutente e multitasking. Bisogna imparare a sfruttare la potenza di queste caratteristiche e le somiglianze tra Unix e GNU/Linux.

Non bisogna scappare dai testi pensati per Unix e affidarsi solamente a testi su GNU/Linux dato che in questo modo ci si priva di molte informazioni utili.

| Nota
Se si è usato tramite strumenti a riga di comando un sistema *nix per un certo tempo, probabilmente si sa già tutto ciò che viene spiegato qui. Si usi questa sezione come un ripasso e per consultazioni.

## 1.1. Nozioni di base sulla console

### 1.1.1. Il prompt di shell

All'avvio del sistema, se non è stata installato alcun ambiente con GUI come il sistema desktop GNOME o KDE. Supponiamo che il proprio nome host sia `pippo`, il prompt di login apparirà come segue.

Se è stato installato un ambiente GUI, allora ci si può comunque spostare ad un prompt di login a caratteri premendo Ctrl-Alt-F3 e si può ritornare alla GUI con Ctrl-Alt-F2 (vedere Sezione 1.1.6, «Console virtuali» in seguito per maggiori informazioni).

    foo login:

Al prompt di login digitare il proprio nome utente, ad esempio `pinguino` e premere il tasto Invio, poi digitare la propria password e premere di nuovo Invio.

| Nota
Nella tradizione Unix, il nome utente e la password di un sistema Debian distinguono le lettere maiuscole dalle minuscole. Il nome utente di solito viene scelto usando solo lettere minuscole. Il primo account utente viene normalmente creato durante l'installazione. Account utente aggiuntivi possono essere creati da root con adduser(8).

Il sistema si presenta con il messaggio di benvenuto memorizzato in "`/etc/motd`" (Message Of The Day, messaggio del giorno) e fornisce un prompt dei comandi.

    Debian GNU/Linux 12 foo tty3

    foo login: penguin
    Password:

    Linux foo 6.5.0-0.deb12.4-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.5.10-1~bpo12+1 (2023-11-23) x86_64

    The programs included with the Debian GNU/Linux system are free software;
    the exact distribution terms for each program are described in the
    individual files in /usr/share/doc/*/copyright.

    Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
    permitted by applicable law.

    Last login: Wed Dec 20 09:39:00 JST 2023 on tty3
    foo:~$

Si è ora nella shell. La shell interpreta i comandi dell'utente.

### 1.1.2. Il prompt di shell in una GUI

Se è stato installato un ambiente con GUI durante l'installazione, all'avvio del sistema viene presentata una schermata grafica di login. Si inseriscono il nome utente e la password per fare il login come utente non privilegiato. Usare il tasto Tab per spostarsi dal campo del nome utente a quello della password e viceversa, oppure usare il mouse e il clic principale.

Si può ottenere il prompt di shell in un ambiente GUI avviando un programma `emulatore di terminale X` come gnome-terminal(1), rxvt(1) o xterm(1). Nell'ambiente desktop GNOME può essere fatto premendo il tasto SUPER (tasto Windows) e digitando "terminal" per cercare il prompt.

In altri sistemi Desktop (come `fluxbox`), potrebbe non esserci un punto evidente per l'apertura del menu. Se si è in questa condizione, provare a fare clic, con il tasto destro, sullo sfondo della schermata del desktop e sperare che appaia un menu.

### 1.1.3. L'account root

L'account root viene anche indicato come superutente o utente privilegiato. Da questo account si possono eseguire i seguenti compiti amministrativi.

- Leggere, scrivere e cancellare qualsiasi file sul sistema indipendentemente dai suoi permessi.

- Impostare il proprietario e i permessi di qualunque file sul sistema.

- Impostare la password di qualsiasi utente non privilegiato nel sistema.

- Fare il login in qualsiasi account senza la password.

Questi poteri illimitati dell'account root rendono necessario essere prudenti e responsabili nel loro uso.

| Avvertimento
Non comunicare mai la password di root ad altri.

| Nota

I permessi di un file (inclusi i device hardware come CD-ROM, ecc. che sono nient'altro che un altro file per il sistema Debian) lo possono rendere inutilizzabile o inaccessibile per gli utenti non root. Benché usare l'account root sia un metodo veloce per affrontare questo tipo di situazione, la sua soluzione dovrebbe essere l'impostazione degli appropriati permessi e gruppi proprietari per il file (vedere Sezione 1.2.3, «Permessi del file system»).

### 1.1.4. Il prompt di shell di root

Ecco alcuni metodi di base per ottenere il prompt di shell per root usando la password di root.

- Inserire `root` al prompt di login a caratteri.

- Digitare "`su -l`" al prompt di shell di un utente qualsiasi.

  - L'ambiente dell'utente attuale non viene in questo caso preservato.

- Digitare "`su`" al prompt di shell di un utente qualsiasi.

  - L'ambiente dell'utente attuale viene in questo caso parzialmente preservato.

### 1.1.5. Strumenti di amministrazione del sistema con interfaccia utente grafica

Quando il menu del desktop non avvia gli strumenti con interfaccia grafica per l'amministrazione di sistema con i privilegi appropriati, si può avviarli dal prompt di shell di root degli emulatori di terminale, quali gnome-terminal(1), rxvt(1) o xterm(1). Vedere Sezione 1.1.4, «Il prompt di shell di root» e Sezione 7.9, «Connessione a server X».

| Avvertimento
Non avviare mai il gestore di sessioni/display manager della GUI dall'account root inserendo `root` al prompt di un display manager come gdm3(1). Non eseguire mai in X Window programmi con interfaccia utente grafica non fidati da remoto quando sono visualizzate informazioni critiche, dato che potrebbero spiare lo schermo X.

### 1.1.6. Console virtuali

Nel sistema Debian standard, ci sono sei console a caratteri in stile VT100 disponibili tra cui ci si può spostare per avviare una shell di comando direttamente sull'host Linux. A meno che non si sia in un ambiente con interfaccia grafica, si può passare da una console virtuale all'altra usando simultaneamente il `tasto_Alt_sinistro` e uno dei tasti `F1` — `F6`. Ogni console a caratteri permette un login indipendente nell'account e offre un ambiente multiutente. L'ambiente multiutente è una bellissima caratteristica di Unix e ci si può abituare presto a dipendere da esso.

Se si è nell'ambiente con GUI, si accede alla console a caratteri 3 premendo i tasti `Ctrl-Alt-F3`, cioè premendo contemporaneamente il `tasto_Ctrl_sinistro`, il `tasto_Alt_sinistro` e il `tasto_F3`. Si può tornare all'ambiente GUI, che di solito è in esecuzione sulla console virtuale 2, premendo `Alt-F2`.

In alternativa ci si può spostare in un'altra console virtuale, per esempio la console 3, dalla riga di comando.

    # chvt 3

### 1.1.7. Come uscire dal prompt dei comandi

Si digita `Ctrl-D`, cioè il `tasto_Ctrl_sinistro` e il `tasto_d` vengono premuti contemporaneamente al prompt dei comandi per chiuderà l'attività della shell. Se si è nella console a caratteri, in questo modo si ritorna al prompt di login. Anche se questi caratteri di controllo vengono indicati con le lettere maiuscole, come "control D", non è necessario premere il tasto Maiusc. Per indicare `Ctrl-D` viene anche usata l'espressione abbreviata `^D`. In alternativa si può digitare "exit".

Se si sta usando x-terminal-emulator(1) , in questo modo si può chiudere la finestra dell'emulatore di terminale (`x-terminal-emulator`).

### 1.1.8. Come spegnere il sistema

Esattamente come ogni altro SO moderno in cui le operazioni su file comportano una cache dei dati in memoria per migliorare le prestazioni, il sistema Debian ha bisogno della appropriata procedura di spegnimento prima che l'alimentazione possa essere staccata in modo sicuro. Questo serve a preservare l'integrità dei file, forzando la scrittura su disco di tutti i cambiamenti avvenuti in memoria. Se è disponibile il controllo software dell'alimentazione, la procedura di spegnimento automaticamente toglie l'alimentazione al sistema. (In caso contrario può essere necessario tener premuto per alcuni secondi il tasto di accensione/spegnimento.)

Si può spegnere il sistema dalla riga di comando nella normale modalità multiutente.

    # shutdown -h now

Si può spegnere il sistema dalla riga di comando nella modalità single-user.

    # poweroff -i -f

Vedere Sezione 6.3.8, «Spegnere il sistema remoto su SSH».

### 1.1.9. Ripristinare una console funzionante

Quando, dopo aver fatto qualcosa di strano come "`cat un-qualche-file-binario`", lo schermo impazzisce digitare "`reset`" al prompt dei comandi. Mentre lo si digita il comando potrebbe non essere visualizzato. Si può anche usare "`clear`" per pulire lo schermo.

### 1.1.10. Suggerimenti per pacchetti aggiuntivi per i principianti

Sebbene anche l'installazione minima del sistema Debian, senza alcun ambiente desktop, fornisca le funzionalità Unix di base è una buona idea installare con apt-get(8) alcuni pacchetti aggiuntivi per la riga di comando e i terminali a caratteri basati su curses, come `mc` e `vim` con cui i principianti possono fare i primi passi. Eseguire i comandi seguenti.

    # apt-get update
     ...
    # apt-get install mc vim sudo aptitude
     ...

Se questi pacchetti sono già installati, nessun nuovo pacchetto sarà installato.

Tabella 1.1. Elenco di pacchetti con interessanti programmi in modalità testuale

pacchetto | popcon | dimensione | descrizione
--- | --- | --- | ---
`mc` | V:41, I:182 | 1590 | Gestore di file testuale a tutto schermo
`sudo` | V:750, I:866 | 6774 | Programma per garantire privilegi di root limitati agli utenti
`vim` | V:85, I:347 | 4135 | Editor di testi Unix Vi IMproved, un editor di testi per programmatori (versione standard)
`vim-tiny` | V:57, I:979 | 1862 | Editor di testi Unix Vi IMproved, un editor di testi per programmatori (versione compatta)
`emacs-nox` | V:3, I:13 | 46564 | Emacs dal progetto GNU, l'editor di testi estensibile basato su Lisp
`w3m` | V:11, I:137 | 2853 | Browser Web testuali
`gpm` | V:8.7, I:9.5 | 524 | Taglia e Incolla in stile Unix nella console testuale (demone)

Potrebbe essere una buona idea leggere un po' di documentazione.

Tabella 1.2. Elenco di pacchetti con documentazione interessante

pacchetto | popcon | dimensione | descrizione
--- | --- | --- | ---
`doc-debian` | I:883 | 185 | Documentazione del Progetto Debian, (FAQ Debian) ed altri documenti
`debian-policy` | I:7.4 | 5147 | Manuale Debian Policy e documenti correlati
`developers-reference` | V:0.2, I:2.4 | 2635 | Linee guida ed informazioni per gli sviluppatori Debian
`debmake-doc` | I:0.37 | 11807 | Guida Debian per il Manutentore
`debian-history` | I:0.52 | 6251 | Storia del Progetto Debian
`debian-faq` | I:881 | 791 | FAQ Debian

Si possono installare alcuni di questi pacchetti usando i comandi seguenti.

    # apt-get install package_name

### 1.1.11. Un account utente extra

Se non si vuole usare il proprio account utente principale per le esercitazioni descritte in seguito, si può creare un account utente per esercitarsi, ad esempio `pesce` con il comando seguente.

    # adduser fish

Rispondere a tutte le domande.

In questo modo si crea un nuovo account chiamato `pesce`. Dopo aver fatto pratica si può rimuover questo account e la sua directory home digitando quanto segue.

    # deluser --remove-home fish

Nei sistemi non Debian e Debian specializzati, le attvità descritte sopra devono usare invece le utilità a basso livello useradd(8) e userdel(8).

### 1.1.12. Configurazione di sudo

Per la tipica postazione di lavoro di un unico utente, come il sistema desktop Debian su un PC portatile, è frequente l'uso di una semplice configurazione di sudo(8), come qui di seguito descritto, per permettere all'utente non privilegiato, ad esempio `pinguino`, di ottenere privilegi di amministratore con la sola propria password, senza quella dell'utente root.

    # echo "penguin  ALL=(ALL) ALL" >> /etc/sudoers

In alternativa è uso comune usare la configurazione seguente per permettere all'utente non privilegiato, ad esempio `pinguino`, di ottenere privilegi di amministratore senza alcuna password.

    # echo "penguin  ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers

Questo trucco dovrebbe essere usato esclusivamente per le postazioni di lavoro con un solo utente, in cui l'utente è anche l'amministratore.

| Avvertimento
Non impostare account per utenti regolari su postazioni di lavoro multi-utente in questo modo perché ciò sarebbe un grosso problema per la sicurezza del sistema.

| Attenzione

Nell'esempio precedente la password e l'account di `pinguino` richiedono altrettanta protezione della password e account dell'utente root.

I privilegi di amministrazione in questo contesto sono forniti a qualcuno che è autorizzato ad eseguire i compiti di amministrazione del sistema sulla macchina. Non dare mai tali privilegi ad un manager del dipartimento di Amministrazione della propria azienda o al proprio capo, a meno che non siano autorizzati e capaci.

| Nota

Per fornire privilegi di accesso a specifici device e file, si dovrebbe considerare l'uso dei gruppi per dare un accesso limitato, invece di usare i privilegi di `root` attraverso sudo(8).

Con una configurazione più attenta e precisa, sudo(8) può garantire privilegi amministrativi limitati ad altri utenti in un sistema condiviso, senza rendere nota la password di root. Questo può aiutare la tracciabilità su host con più di un amministratore, in modo che si possa dire chi ha fatto cosa. D'altra parte si potrebbe anche volere che nessuno abbia tali privilegi.

### 1.1.13. Tempo di giocare

Si è ora pronti a giocare con il sistema Debian senza rischi fintanto che si usa l'account utente non privilegiato.

Ciò è possibile perché il sistema Debian è, anche subito dopo l'installazione predefinita, configurato con i permessi dei file corretti che impediscono agli utenti non privilegiati di danneggiare il sistema. Ci possono essere naturalmente ancora dei punti deboli che possono essere sfruttati, ma chi si preoccupa di tali cose non dovrebbe leggere questa sezione ma piuttosto il manuale Securing Debian.

Si può imparare il sistema Debian, come sistema *nix nelle sezioni seguenti.

- Sezione 1.2, «File system stile Unix» (concetti di base)

- Sezione 1.3, «Midnight Commander (MC)» (sopravvivere)

- Sezione 1.4, «Ambiente di lavoro di base in stile Unix» (lavoro di base)

- Sezione 1.5, «Il semplice comando di shell» (uso della shell)

- Sezione 1.6, «Elaborazione di testo stile Unix» (elaborazione di testi)

## 1.2. File system stile Unix

In GNU/Linux ed altri sistemi operativi *nix, i file sono organizzati in directory. Tutti i file e le directory sono organizzati in un unico grande albero che ha la sua radice in "`/`". Viene chiamato albero perché il file system, se viene disegnato, ha l'aspetto di un albero messo però sottosopra.

Questi file e directory possono essere sparsi su diversi dispositivi. mount(8) serve per attaccare il file system trovato su un qualche dispositivo al grande albero dei file. Al contrario, umount(8) lo stacca. Nei kernel Linux recenti mount(8) con alcune opzioni può collegare parte di un albero dei file in qualche altra posizione o può montare file system come condivisi, privati, slave o non-collegabili. Le opzioni di montaggio supportate per ciascun file system sono disponibili in "`/usr/share/doc/linux-doc-*/Documentation/filesystems/`".

Nei sistemi Unix vengono chiamate directory quelle che in altri sistemi sono chiamate cartelle. Notare anche che non esiste in nessun sistema Unix un concetto di unità, come "`A:`". C'è un solo unico file system e tutto vi è incluso. Questo è un grandissimo vantaggio rispetto a Windows.

### 1.2.1. Nozioni di base sui file Unix

Ecco alcune nozioni di base sui file Unix.

- Nei nomi dei file si distingue tra maiuscole e minuscole. I file "`MIOFILE`" e "`MioFile`" sono cioè file diversi.

- La directory root indica la radice del file system, indicata semplicemente con "`/`". Non la si confonda con la directory home dell'utente root: "`/root`".

- Ogni directory ha un nome che può contenere qualsiasi lettera o simbolo tranne"`/`". La directory radice è un'eccezione; il suo nome è "`/`" (pronunciato "slash" o "directory root/radice") e il suo nome non può essere cambiato.

- Ogni file o directory è indicato da un nome di file pienamente qualificato, un nome file assoluto o un percorso, fornendo la sequenza di directory attraverso le quali si deve passare per raggiungerlo. I tre termini sono sinonimi.

- Tutti i nomi di file pienamente qualificati iniziano con la directory "`/`" e c'è un carattere "`/`" tra ciascuna directory o file nel nome del file. Il primo carattere "`/`" è la directory di più alto livello e gli altri "`/`" separano le directory successive fino a che non si raggiunge l'ultima voce che è il nome del file stesso. I termini usati possono creare confusione. Prendere in considerazione come esempio il seguente nome file pienamente qualificato come esempio: "`/usr/share/keytables/us.map.gz`"; anche se ci si riferisce al solo nome base, "`us.map.gz`" come al suo nome file.

- La directory radice ha un certo numero di rami, come "`/etc/`" e "`/usr/`". Queste sottodirectory a loro volta si diramano in ulteriori sottodirectory, come "`/etc/systemd/`" e "`/usr/local/`". Viste tutte insieme vengono chiamate albero delle directory. Si può pensare ad un nome file assoluto come ad un percorso dalla base dell'albero ("`/`") alla punta di un ramo (un file). Si può anche sentir parlare dell'albero delle directory come se fosse un albero genealogico che comprende tutti i discendenti di un'unica figura detta directory radice ("`/`): le sottodirectory hanno perciò dei genitori e un percorso mostra gli antenati completi di un file. Ci sono anche percorsi relativi che iniziano da una qualche posizione che non sia la directory radice. Si dovrebbe tenere a mente che la directory "`../`" si riferisce alla directory genitore. Questa terminologia si applica anche ad altre strutture simili a quella delle directory, come le strutture di dati gerarchici.

- Non c'è alcun nome speciale di percorso di directory che corrisponda ad un dispositivo fisico, come il disco fisso. Questa è una differenza rispetto a RT-11, CP/M, OpenVMS, MS-DOS, AmigaOS e Microsoft Windows, in cui il percorso contiene una porzione con il nome di dispositivo come "`C:\`". (Esistono tuttavia directory che si riferiscono ai dispositivi fisici come a parte del file system normale. Vedere Sezione 1.2.2, «Aspetti tecnici del file system».)

| Nota

Benché si possa usare quasi qualsiasi lettera o simbolo nel nome di un file, in pratica farlo non è una bella idea. È meglio evitare qualsiasi carattere che ha spesso un significato particolare sulla riga di comando, inclusi spazi, tabulazioni, a capo e altri caratteri speciali: `{ } ( ) [ ] ' ` " \ / > < | ; ! # & ^ * % @ $`. Se si vuole separare delle parole all'interno di un nome file, buone alternative sono un punto, un trattino ed il segno di sottolineatura. Si può anche scrivere in maiuscolo ogni parola, "`InQuestoModo`". Gli utenti Linux esperti tendono ad evitare l'uso degli spazi nei nomi dei file.

| Nota
La parola "root" può significare l'"utente root" o la "directory root". Il contesto in cui il termine viene usato dovrebbe rendere chiaro il suo significato.

| Nota
La parola percorso non è usata solamente per un nome di file pienamente qualificato come descritto in precedenza, ma anche per il percorso di ricerca dei comandi. Il significato è di solito reso chiaro dal contesto.

Le linee guida raccomandate per la gerarchia dei file sono descritte in dettaglio nel Filesystem Hierarchy Standard ("`/usr/share/doc/debian-policy/fhs/fhs-2.3.txt.gz`" e in hier(7)). Come inizio si dovrebbe tenere a mente quanto segue.

Tabella 1.3. Elenco degli usi delle directory principali

directory | uso della directory
--- | ---
`/` | la directory root
`/etc/` | file di configurazione a livello di sistema
`/var/log/` | file di registro del sistema
`/home/` | tutte le directory home degli utenti non privilegiati

### 1.2.2. Aspetti tecnici del file system

Nella scia della tradizione Unix, il sistema Debian GNU/Linux fornisce il file system in cui risiedono i dati fisici nel disco fisso e negli altri dispositivi di memorizzazione, ed inoltre le interazioni con i dispositivi hardware come gli schermi delle console e le console seriali remote vengono rappresentate in un modo unificato in "`/dev/`".

Ogni file, directory, pipe con nome (un modo per due programmi di scambiare dati) o dispositivo fisico presente in un sistema Debian GNU/Linux ha una struttura di dati chiamata inode che descrive gli attributi ad esso associati come l'utente che lo possiede (proprietario), il gruppo a cui appartiene, la data dell'ultimo accesso ad esso, ecc. L'idea di rappresentare praticamente tutto nel file system è stata un'innovazione di Unix e i kernel Linux moderni hanno sviluppato questa idea e sono andati oltre. Ora anche le informazioni sui processi in esecuzione sul computer possono essere trovate nel file system.

La rappresentazione astratta e unificata di entità fisiche e di processi interni è molto potente dato che permette di usare lo stesso comando per lo stesso tipo di operazione su molti tipi di device completamente diversi l'uno dall'altro. È anche possibile cambiare il modo in cui il kernel funziona scrivendo dati in file speciali che sono collegati ai processi in esecuzione.

| Suggerimento
Per identificare la corrispondenza tra l'albero dei file e le entità fisiche, eseguire mount(8) senza opzioni.

### 1.2.3. Permessi del file system

I permessi del file system di sistemi *nix sono definiti e influenzano tre categorie di utenti.

- L'utente che è il proprietario del file (u).

- Gli altri utenti del gruppo a cui appartiene il file (g).

- Tutti gli altriutenti (o) a cui ci si riferisce anche con i termini "mondo" e "tutti".

Per un file, a ciascun permesso corrispondono le seguenti azioni.

- Il permesso di lettura (r) permette al proprietario di esaminare il contenuto del file.

- Il permesso di scrittura (w) permette al proprietario di modificare il file.

- Il permesso di esecuzione (x) permette al proprietario di eseguire il file come comando.

Per una directory, a ciascun permesso corrispondono le seguenti azioni.

- Il permesso di lettura (r) permette al proprietario di elencare il contenuto della directory.

- Il permesso di scrittura (w) permette al proprietario di aggiungere o rimuovere file dalla directory.

- Il permesso di esecuzione (x) permette al proprietario di accedere ai file nella directory.

In questo caso il permesso di esecuzione su una directory non solo significa poter leggere i file in quella directory ma anche poterne vedere gli attributi, come la dimensione e la data di modifica.

Per visualizzare le informazioni sui permessi (ed altro) di file e directory si usa ls(1). Quando chiamato con l'opzione "`-l`" mostra, nell'ordine elencato in seguito, le seguenti informazioni.

- Tipo di file (primo carattere).

- Permessi di accesso al file (nove caratteri, tre ciascuno per utente, gruppo e altri, in questo ordine).

- Numero di collegamenti fisici al file.

- Nome dell'utente proprietario del file.

- Nome del gruppo a cui il file appartiene.

- Dimensione in caratteri (byte) del file.

- Data ed ora del file (mtime).

- Nome del file.

Tabella 1.4. Elenco dei valori possibili per il primo carattere nell'output di "`ls -l`"

carattere | significato
--- | ---
`-` | file normale
`d` | directory
`l` | collegamento simbolico
`c` | device a caratteri
`b` | device a blocchi
`p` | pipe con nome
`s` | socket

Per cambiare il proprietario di un file da un account root si usa chown(1). Per cambiare il gruppo di un file dall'account del proprietario o da quello di root si usa chgrp(1). Per cambiare i permessi di accesso di file o directory dall'account del proprietario o da quello di root si usa chmod(1). La sintassi di base per manipolare un file `pippo` è la seguente.

    # chown newowner foo
    # chgrp newgroup foo
    # chmod  [ugoa][+-=][rwxXst][,...] foo

Per esempio si può fare in modo che l'utente `pippo` sia il proprietario di un albero di directory condivisa dal gruppo `pluto` con i seguenti comandi.

    # cd /some/location/
    # chown -R foo:bar .
    # chmod -R ug+rwX,o=rX .

Ci sono altri tre bit speciali di permessi.

- Il bit set user ID (s o S al posto del permesso x dell'utente).

- Il bit set group ID (s o S al posto del permesso x del gruppo).

- Il bit sticky (t o T al posto del permesso x degli altri).

Nell'output di "`ls -l`" il valore di questi bit è maiuscolo se il bit di permesso di esecuzione nascosto da essi è non impostato.

L'impostazione del bit set user ID per un file eseguibile permette ad un utente di eseguire quel file con l'ID del proprietario del file (per esempio root). In modo simile, l'impostazione del bit set group ID per un file eseguibile permette ad un utente di eseguire il file con l'ID del gruppo a cui appartiene il file (per esempio root). Poiché l'impostazione di questi bit può causare rischi in termini di sicurezza, il loro uso richiede una particolare cautela.

L'impostazione del bit set group ID per una directory abilita lo schema di creazione di file in stile BSD, in cui tutti i file creati nella directory appartengono al gruppo della directory.

L'impostazione dello sticky bit per una directory impedisce la rimozione di un file nella directory da parte dell'utente che non ne è il proprietario. Per preservare i contenuti di un file in directory con permessi di scrittura per tutti, come "`/tmp`" o in directory con permessi di scrittura per un gruppo, non solo si deve impostare il permesso di scrittura per il file, ma anche impostare lo sticky bit per la directory. In caso contrario, qualunque utente con i permessi di scrittura per la directory può rimuovere il file e crearne uno nuovo con lo stesso nome.

Ecco alcuni interessanti esempi di permessi dei file.

    $ ls -l /etc/passwd /etc/shadow /dev/ppp /usr/sbin/exim4
    crw------T 1 root root   108, 0 Oct 16 20:57 /dev/ppp
    -rw-r--r-- 1 root root     2761 Aug 30 10:38 /etc/passwd
    -rw-r----- 1 root shadow   1695 Aug 30 10:38 /etc/shadow
    -rwsr-xr-x 1 root root   973824 Sep 23 20:04 /usr/sbin/exim4
    $ ls -ld /tmp /var/tmp /usr/local /var/mail /usr/src
    drwxrwxrwt 14 root root  20480 Oct 16 21:25 /tmp
    drwxrwsr-x 10 root staff  4096 Sep 29 22:50 /usr/local
    drwxr-xr-x 10 root root   4096 Oct 11 00:28 /usr/src
    drwxrwsr-x  2 root mail   4096 Oct 15 21:40 /var/mail
    drwxrwxrwt  3 root root   4096 Oct 16 21:20 /var/tmp

Esiste un metodo numerico alternativo per descrivere i permessi dei file con chmod(1); tale metodo numerico usa numeri ottali (base=8) di 3 o 4 cifre.

Tabella 1.5. Permessi in notazione numerica per i comandi chmod(1)

cifra | significato
--- | ---
1ª cifra opzionale | somma di set user ID (=4), set group ID (=2) e sticky bit (=1)
2ª cifra | somma dei permessi di lettura (=4), scrittura (=2) e esecuzione (=1) per l'utente
3ª cifra | come sopra, ma per ilgruppo
4ª cifra | come sopra, ma per gli altri

Sembra complicato, ma è in realtà piuttosto semplice. Se si guardano le prime colonne (2-10) nell'output del comando "`ls -l`" e le si leggono come una rappresentazione binaria (base=2) dei permessi sui file (dove "-" equivale a "0" e "rwx" equivalgono a "1"), le ultime 3 cifre del valore numerico dei permessi dovrebbero apparire come la corretta rappresentazione dei permessi sui file in numerazione ottale (base=8).

Per esempio, provare a fare quanto segue.

    $ touch foo bar
    $ chmod u=rw,go=r foo
    $ chmod 644 bar
    $ ls -l foo bar
    -rw-r--r-- 1 penguin penguin 0 Oct 16 21:39 bar
    -rw-r--r-- 1 penguin penguin 0 Oct 16 21:35 foo

| Suggerimento
Se si deve aver accesso alle informazioni visualizzate da "`ls -l`" in script di shell, si dovrebbero usare i comandi pertinenti, come test(1), stat(1) e readlink(1). Si possono usare anche i comandi interni della shell come "`[`" o "`test`".

### 1.2.4. Controllo dei permessi per i file appena creati: umask

I permessi che vengono applicati ad un file o una directory appena creati sono limitati dal comando interno della shell `umask`. Vedere dash(1), bash(1) e builtins(7).

     (file permissions) = (requested file permissions) & ~(umask value)

Tabella 1.6. Esempi di valori di umask

umask | permessi dei file creati | permessi delle directory create | uso
--- | --- | --- | ---
`0022` | `-rw-r--r--` | `-rwxr-xr-x` | scrivibile solo dall'utente
`0002` | `-rw-rw-r--` | `-rwxrwxr-x` | scrivibile solo dal gruppo

Il sistema Debian usa, in modo predefinito, uno schema UPG (User Private Group, gruppo privato dell'utente). Ogni volta che viene aggiunto un nuovo utente al sistema, viene creato un UPG; questo ha lo stesso nome dell'utente per il quale è stato creato e quell'utente è l'unico membro dell'UPG. Lo schema UPG rende sicura l'impostazione della umask a `0002` dato che ogni utente ha il proprio gruppo privato. (In alcune varianti di Unix è abbastanza comune impostare tutti gli utenti normali come appartenenti ad un unico gruppo `users` ed è in quel caso una buona idea impostare umask a `0022` per ragioni di sicurezza.)

| Suggerimento
Abilitare UPG inserendo "`umask 002`" nel file `~/.bashrc`.

### 1.2.5. Permessi per gruppi di utenti (gruppi)

| Avvertimento
Assicurarsi di salvare le modifiche non ancora salvate prima di fare il riavvio o azioni simili.

Si può aggiungere l'utente `pinguino` ad un gruppo `uccelli` in due passi:

- Cambiare la configurazione del gruppo usando uno dei modi seguenti:

  - Eseguire "`sudo usermod -aG uccelli pinguino`".

  - Eseguire "`sudo adduser pinguino uccelli`" (solo in sistemi Debian tipici).

  - Eseguire "`sudo vigr`" per `/etc/group` e "`sudo vigr -s`" per `/etc/gshadow` per aggiungere `pinguino` alla fine della riga per `uccelli`.

- Applicare la configurazione usando uno dei due modi seguenti:

  - Spegnimento competo e riaccesso (opzione migliore).

  - Logout via GUI menu and login. (This may not work under the modern Desktop environment.)

Si può rimuovere l'utente `pinguino` dal gruppo `uccelli` in due passi:

- Cambiare la configurazione del gruppo usando uno dei modi seguenti:

  - Eseguire "`sudo usermod -rG uccelli pinguino`".

  - Eseguire "`sudo deluser pinguino uccelli`" (solo in sistemi Debian tipici).

  - Eseguire "`sudo vigr`" per `/etc/group` e "`sudo vigr -s`" per `/etc/gshadow` per rimuovere `pinguino` dalla riga per `uccelli`.

- Applicare la configurazione usando uno dei due modi seguenti:

  - Spegnimento competo e riaccesso (opzione migliore).

  - Eseguire "`kill -TERM -1`" e fare alcune azioni di correzione, come "`systemctl restart NetworkManager.service`".

  - Fare il logout dal menu della GUI non è un'opzione per il desktop GNOME.

Qualsiasi tentativo di riavvio a caldo è un fragile sostituto di un vero riavvio completo nei sistemi desktop moderni.

| Nota
In alternativa, si possono aggiungere dinamicamente gli utenti ai gruppi durante il processo di autenticazione aggiungendo la riga "`auth optional pam_group.so`" al file "`/etc/pam.d/common-auth`" e configurando "`/etc/security/group.conf`". (Vedere Capitolo 4, Autenticazione e controllo degli accessi.)

The hardware devices are just another kind of file on the Debian system. If you have problems accessing devices such as USB flash drive and CD-ROM from a user account, you should make that user a member of the relevant group.

Alcuni importanti gruppi pre-impostati dal sistema permettono ai loro membri l'accesso a file e device particolari senza i privilegi di `root`.

Tabella 1.7. Elenco dei principali gruppi forniti dal sistema per accesso ai file

gruppo | descrizione dei file e device accessibili
--- | ---
`dialout` | accesso diretto e completo alle porte seriali ("`/dev/ttyS[0-3]`")
`dip` | accesso limitato alle porte seriali per connessione IP dialup a peer fidati
`cdrom` | unità CD-ROM, DVD+/-RW
`audio` | device audio
`video` | device video
`scanner` | scanner
`adm` | registri di monitoraggio del sistema
`staff` | alcune directory per compiti minori di amministrazione: ""`/usr/local`", "`/home`"

| Suggerimento
È necessario far parte del gruppo `dialout` per riconfigurare il modem, comporre numeri, ecc. Se però `root` crea file di configurazione predefiniti per i peer fidati in "`/etc/ppp/peers/`", è necessario solamente far parte del grupo `dip` per creare una connessione IP dialup a tali peer fidati usando i comandi pppd(8), pon(1) e poff(1).

Alcuni importanti gruppi pre-impostati dal sistema permettono ai loro membri di eseguire particolari comandi senza i privilegi di `root`.

Tabella 1.8. Elenco dei principali gruppi forniti dal sistema per l'esecuzione di particolari comandi

gruppo | comandi accessibili
--- | ---
`sudo` | execute any command with superuser privileges
`lpadmin` | eseguire comandi per aggiungere, modificare e rimuovere stampanti dal database delle stampanti

Per l'elenco completo degli utenti e gruppi forniti dal sistema, vedere la recente versione del documento "Utenti e gruppi" in "`/usr/share/doc/base-passwd/users-and-groups.html`" fornito dal pacchetto `base-passwd`.

Vedere passwd(5), group(5), shadow(5), newgrp(1), vipw(8), vigr(8) e pam_group(8) per informazioni sui comandi di gestione di utenti e gruppi sul sistema.

### 1.2.6. Orari

Ci sono tre tipi di orari per un file GNU/Linux.

Tabella 1.9. Elenco dei tipi di data

tipo | significato (definizione storica Unix)
--- | ---
mtime | orario di modifica del file (`ls -l`)
ctime | orario di cambiamento di stato del file (`ls -lc`)
atime | orario dell'ultimo accesso al file (`ls -lu`)

| Nota
ctime non è l'orario di creazione del file.

| Nota
L'attuale significato di atime sui sistemi GNU/Linux potrebbe essere diverso dalla sua definizione storica in Unix.

- La sovrascrittura di un file cambia tutti gli attributi mtime, ctime e atime del file.

- Il cambiamento del proprietario o dei permessi di un file cambia gli attributi ctime e atime del file.

- La lettura di un file cambia l'attributo atime di un file nei sistemi Unix storici.

- La lettura di un file cambia l'attributo atime di un file in un sistema GNU/Linux se il file system è montato con "`strictatime`".

- Leggere un file per la prima volta o dopo un giorno modifica l'attributo atime del file stesso su sistemi GNU/Linux, se il filesystem è stato montato con "`relatime`". (comportamento di default da Linux 2.6.30)

- Leggere un file non modifica l'attributo atime del file stesso su sistemi GNU/Linux se il filesystem è stato montato con "`noatime`".

| Nota
Le opzioni di mount "`noatime`" e "`relatime`" sono introdotte per migliorare le prestazioni in lettura del file system nei normali casi d'uso. Semplici operazioni di lettura dei file con l'opzione "`strictatime`" comportano lunghe operazioni di scrittura per aggiornare l'attributo atime. L'attributo atime però è raramente utilizzato, a parte per il file mbox(5). Vedere mount(8).

Usare il comando touch(1) per cambiare l'orario di file esistenti.

Per gli orari, il comando `ls` produce in output stringhe localizzate con la localizzazione non inglese ("`it_IT.UTF-8`").

    $ LANG=C  ls -l foo
    -rw-rw-r-- 1 penguin penguin 0 Oct 16 21:35 foo
    $ LANG=en_US.UTF-8  ls -l foo
    -rw-rw-r-- 1 penguin penguin 0 Oct 16 21:35 foo
    $ LANG=fr_FR.UTF-8  ls -l foo
    -rw-rw-r-- 1 penguin penguin 0 oct. 16 21:35 foo

| Suggerimento
Vedere Sezione 9.3.4, «Visualizzazione personalizzata di date e orari» per personalizzare l'output di "`ls -l`".

### 1.2.7. Collegamenti

Ci sono due metodi per associale un file "`pippo`" ad un diverso nome file "`pluto`".

- Collegamento fisico

  - Nome duplicato per un file esistente

  - "`ln pippo pluto`"

- Collegamento simbolico o symlink

  - File speciale che punta ad un altro file in base al nome

  - "`ln -s pippo pluto`"

Vedere l'esempio seguente per notare i cambiamenti nel conteggio dei collegamenti e le sottili differenze tra i risultati del comando `rm`.

    $ umask 002
    $ echo "Original Content" > foo
    $ ls -li foo
    1449840 -rw-rw-r-- 1 penguin penguin 17 Oct 16 21:42 foo
    $ ln foo bar     # hard link
    $ ln -s foo baz  # symlink
    $ ls -li foo bar baz
    1449840 -rw-rw-r-- 2 penguin penguin 17 Oct 16 21:42 bar
    1450180 lrwxrwxrwx 1 penguin penguin  3 Oct 16 21:47 baz -> foo
    1449840 -rw-rw-r-- 2 penguin penguin 17 Oct 16 21:42 foo
    $ rm foo
    $ echo "New Content" > foo
    $ ls -li foo bar baz
    1449840 -rw-rw-r-- 1 penguin penguin 17 Oct 16 21:42 bar
    1450180 lrwxrwxrwx 1 penguin penguin  3 Oct 16 21:47 baz -> foo
    1450183 -rw-rw-r-- 1 penguin penguin 12 Oct 16 21:48 foo
    $ cat bar
    Original Content
    $ cat baz
    New Content

Il collegamento fisico può essere creato all'interno dello stesso file system e condivide lo stesso numero di inode, come rivela l'opzione "`-i`" di ls(1).

Il collegamento simbolico ha sempre permessi di accesso nominali "`rwxrwxrwx`, come mostrato nell'esempio precedente, ma con gli effettivi permessi di accesso stabiliti dai permessi del file a cui punta.

| Attenzione
In generale è una buona idea non creare collegamenti simbolici complicati o non creare collegamenti fisici per nulla, a meno di non avere una ragione molto buona per farlo. Possono diventare degli incubi quando la combinazione logica dei collegamenti simbolici crea cicli ricorsivi nel file system.

| Nota
È in generale preferibile usare collegamenti simbolici piuttosto che fisici, a meno che non sia abbia una buona ragione per usare un collegamento fisico.

La directory "`.`" punta alla directory in cui appare, perciò il conteggio dei collegamenti per ogni nuova directory inizia da 2. La directory "`..`" punta alla directory genitore, perciò il conteggio dei collegamenti di una directory aumenta con l'aggiunta di nuove sottodirectory.

Se si è appena passati da Windows a Linux, appare presto chiaro come sia ben progettato il collegamento dei nomi di file in Unix se paragonato con i collegamenti in ambiente Windows che sono l'equivalente più prossimo in quel sistema. Dato che sono implementati nel file system, le applicazioni non possono vedere alcuna differenza tra un file collegamento ed un originale. Nel caso di collegamenti fisici, non c'è realmente nessuna differenza.

### 1.2.8. Pipe con nome (FIFO)

Una pipe con nome è un file che si comporta da pipe. Si mette qualcosa dentro il file e questa cosa esce dall'altra parte. Questa è chiamata una FIFO (First-In-First_Out, primo ad entrare-primo ad uscire): la prima cosa che viene immessa nella pipe è la prima ad uscire dall'altra estremità.

Se si scrive su una pipe con nome, il processo che sta eseguendo la scrittura nella pipe non termina fino a che l'informazione scritta nella pipe non viene letta. Se si legge da una pipe con nome, il processo di lettura attende che non ci sia più nulla da leggere prima di terminare. La dimensione della pipe è sempre zero: non archivia dati, ma semplicemente collega due processi come fa la funzionalità fornita dalla sintassi per pipe "`|`" della shell. Tuttavia, dato che questa pipe ha un nome, i due processi non devono essere nella stessa riga di comando e nemmeno essere eseguiti dallo stesso utente. Le pipe sono un'innovazione di Unix di grandissimo impatto.

Per esempio, provare a fare quanto segue.

    $ cd; mkfifo mypipe
    $ echo "hello" >mypipe & # put into background
    [1] 8022
    $ ls -l mypipe
    prw-rw-r-- 1 penguin penguin 0 Oct 16 21:49 mypipe
    $ cat mypipe
    hello
    [1]+  Done                    echo "hello" >mypipe
    $ ls mypipe
    mypipe
    $ rm mypipe

### 1.2.9. Socket

I socket sono usati moltissimo da tutte le comunicazioni Internet, da database e dal sistema operativo stesso. Sono simili alle pipe con nome (FIFO) e permettono ai processi di scambiare informazioni anche tra computer diversi. Per un socket, non è necessario che questi processi siano in esecuzione contemporaneamente, né di essere eseguiti come processi figli di uno stesso processo antenato. Questo è il punto culminante della comunicazione tra processi (IPC). Lo scambio di informazioni può avvenire sulla rete tra host diversi. I due più comuni sono il socket Internet e gli Unix domain socket.

| Suggerimento
"`ss -t -u -a`" (from the `iproute2` package) provides a very useful overview of sockets that are open on a given system.

### 1.2.10. File di device

I file di device fanno riferimento a dispositivi fisici o virtuali sul sistema, come i dischi fissi, la scheda video, lo schermo o la tastiera. Un esempio di dispositivo virtuale è la console, rappresentata da "`/dev/console`".

Ci sono 2 tipi di file di device.

- Device a caratteri

  - Vi si accede un carattere alla volta.

  - 1 carattere = 1 byte

  - Es., device della tastiera, porta seriale, ...

- Device a blocchi

  - Vi si accede in base a unità più grandi chiamate blocchi.

  - 1 blocco > 1 byte

  - Es., dischi fissi, ...

I file di device possono essere letti e scritti, anche se è probabile che i file contengano dati binari che appaiono come farfuglii incomprensibili per le persone. La scrittura diretta di dati in questi file è utile a volte per trovare la soluzione a problemi con le connessioni hardware. Si può, per esempio, fare il dump di un file di testo in un device di stampa "`/dev/lp0`" o inviare comandi del modem alla porta seriale appropriata "`/dev/ttyS0`". Ma, a meno che ciò non venga fatto con cautela, può causare grandissimi disastri. Perciò, essere prudenti.

| Nota
Per il normale accesso ad una stampante, usare lp(1).

I numeri di nodo dei device sono visualizzati se si esegue ls(1) come nell'esempio seguente.

    $ ls -l /dev/sda /dev/sr0 /dev/ttyS0 /dev/zero
    brw-rw---T  1 root disk     8,  0 Oct 16 20:57 /dev/sda
    brw-rw---T+ 1 root cdrom   11,  0 Oct 16 21:53 /dev/sr0
    crw-rw---T  1 root dialout  4, 64 Oct 16 20:57 /dev/ttyS0
    crw-rw-rw-  1 root root     1,  5 Oct 16 20:57 /dev/zero

- "`/dev/sda`" ha major number del device 8 e minor number del device 0. È accessibile in lettura e scrittura dagli utenti che appartengono al gruppo `disk`.

- "`/dev/sr0`" ha major number del device 11 e minor number del device 0. È accessibile in lettura e scrittura dagli utenti che appartengono al gruppo `cdrom`.

- "`/dev/ttyS0`" ha major number del device 4 e minor number del device 64. È accessibile in lettura e scrittura dagli utenti che appartengono al gruppo `dialout`.

- "`/dev/zero`" ha major number del device 1 e minor number del device 5. È accessibile in lettura e scrittura da chiunque.

Nei sistemi Linux moderni il file system sotto "`/dev`" viene popolato automaticamente dal meccanismo udev(7).

### 1.2.11. File di device speciali

Ci sono alcuni file di device speciali.

Tabella 1.10. Elenco di file dei device speciali

file di device | azione | descrizione della risposta
--- | --- | ---
`/dev/null` | lettura | restituisce il "carattere EOF (End of File, fine del file)"
`/dev/null` | scrittura | non ritorna nulla (un pozzo senza fondo in cui buttare via dati)
`/dev/zero` | lettura | ritorna il "carattere `\0` (NUL)", diverso dal numero zero in ASCII
`/dev/random` | lettura | ritorna caratteri a caso da un vero generatore di numeri casuali che dà reale entropia (lento)
`/dev/urandom` | lettura | ritorna caratteri casuali da un generatore di numeri pseudocasuali crittograficamente sicuro
`/dev/full` | scrittura | ritorna l'errore di disco pieno (ENOSPC)

Sono spesso usati insieme alla redirezione di shell (vedere Sezione 1.5.8, «Sequenze tipiche di comandi e ridirezione della shell»).

### 1.2.12. procfs e sysfs

procfs e sysfs, montati in "`/proc`" e "`/sys`" sono pseudo-file system ed espongono strutture interne di dati del kernel nello spazio utente. In altre parole, queste voci sono virtuali, funzionano cioè come una comoda finestra sul funzionamento del sistema operativo.

La directory "`/proc`" contiene (tra le altre cose) una sottodirectory per ciascun processo in esecuzione sul sistema che prende nome dall'ID del processo (PID). Le utilità di sistema, come ps(1), che accedono alle informazioni sui processi, ottengono le loro informazioni da questa struttura di directory.

Le directory in "`/proc/sys/`" contengono interfacce per cambiare certi parametri del kernel durante l'esecuzione. (Si può fare la stessa cosa tramite comandi sysctl(8) specifici o tramite il suo file di precaricamento/configurazione "`/etc/sysctl.d/*.conf`".)

Le persone spesso vanno in panico quando si accorgono di un file in particolare, "`/proc/kcore`" che è particolarmente enorme. È (più o meno) una copia del contenuto della memoria del computer ed è usato per fare il debug del kernel. È un file virtuale che punta alla memoria del computer perciò non ci si preoccupi della sua dimensione.

La directory "`/sys`" contiene strutture dati del kernel esportate, i loro attributi e i collegamenti tra di esse. Contiene anche interfacce per cambiare alcuni parametri del kernel durante l'esecuzione.

Vedere `proc.txt(.gz)`", "`sysfs.txt(.gz)`" e altri documenti correlati nella documentazione del kernel Linux ("`/usr/share/doc/linux-doc-*/Documentation/filesystems/*`") fornita dai pacchetti `linux-doc-*`.

### 1.2.13. tmpfs

tmpfs è un file system temporaneo che contiene tutti i file nella memoria virtuale. I dati del tmpfs nella page cache in memoria possono essere spostati nello spazio di swap su disco quando necessario.

La directory "`/run`" viene montata come il tmpfs nelle prime fasi del processo di avvio. Ciò vi permette la scrittura anche quando la directory "`/`" è montata in sola lettura. Questa è la nuova posizione per la memorizzazione dei file transitori e sostituisce diverse posizioni descritte nella versione 2.3 del Filesystem Hierarchy Standard(Standard per la gerarchia del file system):

- "`/var/run`" → "`/run`"

- "`/var/lock`" → "`/run/lock`"

- "`/dev/shm`" → "`/run/shm`"

Vedere "`tmpfs.txt(.gz)`" nella documentazione del kernel Linux ("`/usr/share/doc/linux-doc-*/Documentation/filesystems/*`") fornita dai pacchetti `linux-doc-*`.

## 1.3. Midnight Commander (MC)

Midnight Commander (MC) è un "coltellino svizzero" GNU per la console Linux ed altri ambienti in terminale. Dà ai principianti la possibilità di usare una console comandata da menu che è molto più facile da imparare dei comandi Unix standard.

Potrebbe essere necessario installare il pacchetto di Midnight Commander che si chiama "`mc`" con il seguente comando.

    $ sudo apt-get install mc

Usare il comando mc(1) per esplorare il sistema Debian. È il modo migliore di imparare. Esplorare qualche posizione interessante usando semplicemente i tasti freccia e il tasto Invio.

- "`/etc`" e le sue sottodirectory

- "`/var/log`" e le sue sottodirectory

- "`/usr/share/doc`" e le sue sottodirectory

- "`/usr/sbin`" e "`/usr/bin`"

### 1.3.1. Personalizzazione di MC

Per far sì che MC cambi la directory di lavoro in uscita e si sposti con `cd` nella directory, suggerisco di modificare "`~/.bashrc`" per includere uno scipt fornito nel pacchetto `mc`.

    . /usr/lib/mc/mc.sh

Vedere mc(1) (sotto l'opzione "`-P`") per capirne la ragione. (Se non è chiaro esattamento quello di cui sto parlando, si può tornare a questo più tardi.)

### 1.3.2. Avvio di MC

MC può essere avviato nel modo seguente.

    $ mc

MC si prende cura di tutte le operazioni sui file attraverso i suoi menu, richiedendo perciò solo un minimo sforzo da parte dell'utente. Premere semplicemente F1 per ottenere la schermata di aiuto. Si può giocherellare con MC premendo semplicemente i tasti freccia e i tasti funzione.

| Nota
In alcune console, come gnome-terminal(1), le pressioni dei tasti funzione potrebbero essere rubate dal programma di console. Si possono disabilitare queste funzionalità per `gnome-terminal` nei menu "Preferenze" → "Generale" e "Scorciatoie".

Se si incontrano problemi di codifica dei caratteri con visualizzazione di caratteri spazzatura, l'aggiunta dell'opzione "`-a`" alla riga di comando di MC può aiutare a prevenirli.

Se ciò non risolve i problemi di visualizzazione in MC, vedere Sezione 8.3.1, «Configurazione del terminale».

### 1.3.3. Gestore dei file in MC

L'impostazione predefinita è con due pannelli di directory contenenti gli elenchi dei file. Un'altra utile modalità è l'impostazione della finestra destra per contenere le "informazioni" per vedere informazioni sui privilegi di accesso dei file, ecc. Di seguito sono elencati alcuni tasti essenziali. Con il demone gpm(8) in esecuzione, si può anche usare il mouse in una console a caratteri Linux. (Assicurarsi di premeri il tasto Maiusc per ottenere il comportamento normale di taglia e incolla in MC.)

Tabella 1.11. Le associazioni dei tasti di MC

tasto | azione associata
--- | ---
`F1` | menu di aiuto
`F3` | visualizzatore interno di file
`F4` | editor interno
`F9` | attiva il menu a tendina
`F10` | esce da Midnight Commander
`Tab` | sposta tra le due finestre
`Insert` o `Ctrl-T` | segna il file per una operazione su più file, come la copia
`Del` | cancella il file (essere prudenti: impostare MC per la modalità di cancellazione sicura)
tasti freccia | intuitivi

### 1.3.4. Trucchetti per la riga di comando di MC

- Il comando `cd` cambia la directory mostrata nel pannello selezionato.

- `Ctrl-Invio` o `Alt-Invio` copia un nome di file nella riga di comando. Usarlo con i comandi cp(1) e mv(1) assieme alla modifica della riga di comando.

- `Alt-Tab` mostra le scelte date dall'espansione di shell dei nomi di file.

- Si possono specificare le directory iniziali per entrambe le finestre come argomenti per MC; per esempio, "`mc /etc /root`".

- `Esc` + `tasto n` → `Fn` (cioè, `Esc` + `1` → `F1`, ecc.; `Esc` + `0` → `F10`)

- Premere `Esc` prima di un tasto ha lo stesso effetto di premere `Alt` ed il tasto contemporaneamente; premere cioè `Esc` + `c` per `Alt-C`. `Esc` è chiamato meta-tasto ed è a volte indicato con "`M-`".

### 1.3.5. L'editor interno di MC

L'editor interno ha un interessante schema per il taglia e incolla. La pressione di `F3` marca l'inizio di una selezione, una seconda pressione di `F3` marca la fine della selezione e la evidenzia. Si può poi muovere il cursore. Se si preme F6, l'area selezionata viene spostata nella posizione del cursore. Se si preme F5 l'area selezionata viene copiata ed inserita alla posizione del cursore. `F2` salva il file. `F10` fa uscire. La maggior parte dei tasti cursore funziona in modo intuitivo.

Si può avviare direttamente questo editor su di un file usando uno dei comandi seguenti.

    $ mc -e filename_to_edit

    $ mcedit filename_to_edit

Questo non è un editor multi-finestra, ma si possono usare più console Linux per ottenere lo stesso effetto. Per copiare tra finestre, usare i tasti Alt-Fn per cambiare console virtuale e usare "File→Insert file" o "File→Copy to file" per spostare una porzione di un file in un altro file.

Questo editor interno può essere rimpiazzato da qualsiasi editor esterno a propria scelta.

Inoltre molti programmi usano la variabile d'ambiente "`$EDITOR`" o "`$VISUAL`" per decidere quale editor usare. Se inizialmente non ci si trova a proprio agio con vim(1) o nano(1), si può impostare queste variabili a "`mcedit`" aggiungendo le righe seguenti al file "`~/.bashrc`".

    export EDITOR=mcedit
    export VISUAL=mcedit

Io raccomando di impostarle a "`vim`", se possibile.

Se non ci si trova a proprio agio con vim(1), si può continuare ad usare mcedit(1) per la maggior parte dei compiti di manutenzione del sistema.

### 1.3.6. Il visualizzatore interno di MC

MC è un visualizzatore molto intelligente. È un grande strumento per cercare parole in documenti. Lo uso sempre per i file nella directory "`/usr/share/doc`". È il metodo più veloce per navigare tra una massa di informazioni Linux. Questo visualizzatore può essere avviato direttamente usando uno dei comandi seguenti.

    $ mc -v path/to/filename_to_view

    $ mcview path/to/filename_to_view

### 1.3.7. Funzionalità di avvio automatico di MC

Se si preme Invio su di un file, un programma appropriato gestirà il contenuto del file (vedere Sezione 9.4.11, «Personalizzare i programmi da avviare»). Questa è una funzionalità molto comoda di MC.

Tabella 1.12. La reazione al tasto Invio in MC

tipo di file | reazione al tasto Invio
--- | ---
file eseguibile | esegue comando
file man | invia i contenuti tramite pipe al software di visualizzazione
file html | invia i contenuti tramite pipe al browser web
file "`*.tar.gz`" e "`*.deb`" | naviga i suoi contenuti come se fosse una sottodirectory

Per far sì che queste funzionalità di visualizzazione dei file e di file virtuali funzionino, i file visualizzabili non dovrebbero essere impostati come eseguibili. Cambiare il loro stato usando chmod(1) o attraverso il menu file di MC.

### 1.3.8. File system virtuale di MC

MC può essere usato per accedere a file in Internet. Premere `F9` per andare nel menu, usare "`Invio`" e "`h`" per attivare un file system Shell. Inserire un URL nella forma "`sh://[utente@]macchina[:opzioni]/[dir-remota]`", che recupera la directory remota che apparirà come una directory locale usando `ssh`.

## 1.4. Ambiente di lavoro di base in stile Unix

Anche se MC permette di fare quasi tutto, è bene imparare come usare gli strumenti a riga di comando invocati dal prompt di shell e prendere familiarità con l'ambiente di lavoro in stile Unix.

### 1.4.1. La shell di login

Dato che la shell di login può essere utilizzata da alcuni programmi di inizializzazione del sistema, è prudente mantenerla come bash(1) e evitare di cambiare la shell di login in chsh(1).

Se si desidera usare un prompt di shell interattiva diverso, impostarlo dalla configurazione dell'emulatore di terminale in GUI o avviarlo da `~/.bashrc`, ad esempio mettendoci "`exec /usr/bin/zsh -i -l`" o "`exec /usr/bin/fish -i -l`".

Tabella 1.13. Elenco di programmi shell

pacchetto | popcon | dimensione | Shell POSIX | descrizione
--- | --- | --- | --- | ---
`bash` | V:888, I:999 | 7276 | Sì | Bash: GNU Bourne Again SHell (standard de facto)
`bash-completion` | V:36, I:958 | 1952 | N/D | completamento programmabile per la shell bash
`dash` | V:928, I:998 | 207 | Sì | Debian Almquist Shell, buona per script di shell
`zsh` | V:41, I:70 | 2499 | Sì | Z shell: la shell standard con molti miglioramenti
`tcsh` | V:4, I:15 | 1366 | No | TENEX C Shell: una versione migliorata di Berkeley csh
`mksh` | V:5.4, I:7.9 | 7713 | Sì | Una versione della Korn shell
`csh` | V:1.1, I:5.4 | 348 | No | C Shell OpenBSD, una versione di Berkeley csh
`sash` | V:0.3, I:5.2 | 1245 | Sì | Stand-alone shell con comandi interni (non adatta per essere la "`/usr/bin/sh`" standard)
`ksh` | V:0.3, I:8.4 | 65 | Sì | la versione reale di AT&T della Korn shell
`rc` | V:0.10, I:0.73 | 182 | No | implementazione della rc shell di AT&T Plan 9
`posh` | V:0.01, I:0.23 | 191 | Sì | Policy-compliant Ordinary SHell (derivata da `pdksh`)

| Suggerimento
Sebbene le shell in stile POSIX condividano la stessa sintassi di base, esse possono differire nel comportamento relativo a cose anche basilari, come le variabili della shell e l'espansione dei modelli glob. Per i dettagli controllare la loro documentazione.

In questo capitolo del tutorial la shell interattiva considerata è sempre `bash`.

### 1.4.2. Personalizzare bash

Si può personalizzare il comportamento di bash(1) con "`~/.bashrc`".

Per esempio provare quanto segue.

    # enable bash-completion
    if ! shopt -oq posix; then
      if [ -f /usr/share/bash-completion/bash_completion ]; then
        . /usr/share/bash-completion/bash_completion
      elif [ -f /etc/bash_completion ]; then
        . /etc/bash_completion
      fi
    fi

    # CD upon exiting MC
    . /usr/lib/mc/mc.sh

    # set CDPATH to a good one
    CDPATH=.:/usr/share/doc:~:~/Desktop:~
    export CDPATH

    PATH="${PATH+$PATH:}/usr/sbin:/sbin"
    # set PATH so it includes user's private bin if it exists
    if [ -d ~/bin ] ; then
      PATH="~/bin${PATH+:$PATH}"
    fi
    export PATH

    EDITOR=vim
    export EDITOR

| Suggerimento
Si possono trovare altri suggerimenti sulla personalizzazione di `bash`, come Sezione 9.3.6, «Comandi colorati», in Capitolo 9, Suggerimenti per il sistema.

| Suggerimento
Il pacchetto `bash-completion` permette il completamento automatico per `bash`.

### 1.4.3. Associazioni di tasti speciali

Nell'ambiente *nix, ci sono alcune associazioni di tasti che hanno un significato speciale. Notare che in una console a caratteri Linux normale solo i tasti `Ctrl` e `Alt`sinistri funzionano come atteso. Ecco alcune combinazioni di tasti che vale la pena ricordare.

Tabella 1.14. Elenco di associazioni di tasti per bash

tasto | descrizione dell'associazione di tasti
--- | ---
`Ctrl-U` | cancella il contenuto della riga prima del cursore
`Ctrl-H` | cancella il carattere prima del cursore
`Ctrl-D` | termina l'input (se si sta usando la shell, esce dalla shell)
`Ctrl-C` | termina un programma in esecuzione
`Ctrl-Z` | arresta temporaneamente un programma spostandolo come compito sullo sfondo
`Ctrl-S` | ferma l'output a schermo.
`Ctrl-Q` | riattiva l'output a schermo.
`Ctrl-Alt-Del` | riavvia/ferma il sistema, vedere inittab(5)
`Left-Alt-key` (opzionalmente, `tasto Windows`) | meta-tasto per Emacs e interfacce utente simili
`freccia in su` | avvia la ricerca nello storico dei comandi in `bash`
`Ctrl-R` | inizia una ricerca incrementale nello storico dei comandi in `bash`
`Tab` | completa l'input di un nome di file nella riga di comando in `bash`
`Ctrl-V` `Tab` | inserisce in input un carattere `Tab` senza espansione nella riga di comando in `bash`

| Suggerimento
La funzionalità di `Ctrl-S` nel terminale può essere disabilitata usando stty(1).

### 1.4.4. Operazioni del mouse

Il funzionamento del mouse per il testo nel sistema Debian mescola 2 stile con alcune peculiarità:

- Funzioni del mouse in stile Unix tradizionali:

  - uso di 3 pulsanti (clic)

  - uso di PRIMARY (principale)

  - usato da applicazioni X come `xterm` e applicazioni testuali nella console Linux

- Funzionamento del mouse moderno in stile GUI:

  - uso di 2 pulsanti (trascina e clic)

  - uso di PRIMARY (principale) e CLIPBOARD (appunti)

  - usato in applicazioni GUI moderne come `gnome-terminal`

Tabella 1.15. Elenco di funzioni del mouse e relative azioni dei tasti in Debian

azione | risposta
--- | ---
Clic sinistro e trascinamento | marca l'intervallo della selezione PRINCIPALE
Clic sinistro | marca l'inizio dell'intervallo per la selezione PRINCIPALE
Clic destro (tradizionale) | marca la fine dell'intervallo per la selezione PRINCIPALE
Clic destro (moderno) | menu dipendente dal contesto (taglia/copia/incolla)
Clic di mezzo o Maiusc-`Ins` | inserisce la selezione PRINCIPALE alla posizione del cursore
`Ctrl-X` | taglia la selezione PRINCIPALE negli APPUNTI
`Ctrl-C` (`Shift-Ctrl-C` nel terminale) | copia la selezione PRINCIPALE negli APPUNTI
`Ctrl-V` | incolla gli APPUNTI alla posizione del cursore

Qui, la selezione PRINCIPALE è l'intervallo di testo evidenziato. All'interno del programma di terminale viene usato invece `Shift-Ctrl-C` per evitare di terminare un programma in esecuzione.

La rotella centrale presente nei mouse moderni viene considerata come il pulsante di mezzo e può essere usata per fare il corrispondente clic. Cliccare contemporaneamente con i pulsanti destro e sinistro funziona da clic di mezzo nelle situazioni in cui si hanno mouse a 2 pulsanti.

Per poter usare il mouse in una console a caratteri Linux, è necessario che gpm(8) sia in esecuzione come demone.

### 1.4.5. Il paginatore

Il comando less(1) è il paginatore (navigatore del contenuto dei file) migliorato. Legge il file specificato nell'argomento del comando o il suo standard input. Premere "`h`" se si ha bisogno di aiuto nella navigazione con il comando `less`. Può fare molto di più di more(1) e può essere fornito di superpoteri eseguendo "`eval $(lesspipe)`" o "`eval $(lessfile)`" nello script di avvio della shell. Vedere ulteriori informazioni in "`/usr/share/doc/less/LESSOPEN`". L'opzione "`-R`" permette output raw e abilita le sequenze di escape ANSI per i colori. Vedere less(1).

| Suggerimento
Nel comando `less` digitare "`h`" per vedere la schermata di aiuto, digitare "`/`" o "`?`" per cercare una stringa e digitare "`-i`" per cambiare la sensibilità a maiuscole/minuscole.

### 1.4.6. L'editor di testo

Si dovrebbe diventare competenti in una delle varianti dei programmi Vim o Emacs che sono popolari sui sistemi *nix.

Penso che abituarsi ai comandi Vim sia la cosa giusta da fare, dato che un editor Vi è sempre presente nel mondo Linux/Unix. (In realtà, il `vi` originale o il nuovo `nvi` sono programmi che si trovano ovunque. Io ho scelto invece Vim per i principianti dato che offre l'aiuto attraverso il tasto `F1` pur essendo abbastanza simile e più potente.)

Se si sceglie invece Emacs o XEmacs come editor preferito, si sta facendo comunque davvero un'ottima scelta, specialmente per la programmazione. Emacs ha una vastità di altre funzionalità, incluso il funzionamento come newsreader, editor di directory, programma di posta, ecc. Quando usato per la programmazione o la scrittura di script, riconosce intelligentemente il formato che si sta usando e cerca di fornire assistenza. Alcune persone sostengono che l'unico programma di cui hanno bisogno su Linux è Emacs. Dieci minuti spesi ad imparare Emacs ora possono far risparmiare ore in futuro. È caldamente raccomandato avere a portata di mano il manuale di GNU Emacs da consultare quando si sta imparando Emacs.

Tutti questi programmi sono di solito forniti con un programma tutor che aiuta ad impararli facendo pratica. Avviare Vim digitando "`vim`" e premere il tasto F1. Si dovrebbero leggere come minimo le prime 35 righe. Poi seguire il corso di apprendimento in linea muovendo il cursore su "`|tutor|`" e premendo `Ctrl-]`.

| Nota
I buoni editor, come Vim ed Emacs, possono gestire correttamente testi UTF-8 e testi in altre codifiche esotiche. È opportuno usare l'ambiente GUI con la localizzazione UTF-8 e installare i programmi e i tipi di carattere necessari. Gli editor hanno opzioni per impostare la codifica dei file indipendentemente dall'ambiente GUI. Fare riferimento alla loro documentazione sui testi multibyte.

### 1.4.7. Impostare un editor di testi predefinito

Debian è fornita con svariati editor differenti. Si raccomanda di installare, come detto in precedenza, il pacchetto `vim`.

Debian fornisce un accesso unificato all'editor predefinito di sistema attraverso il comando "`/usr/bin/editor`" in modo che altri programmi (ad esempio reportbug(1)) possano richiamarlo. Lo si può modificare con il comando seguente.

    $ sudo update-alternatives --config editor

Io raccomando ai principianti la scelta di "`/usr/bin/vim.basic`" invece di"`/usr/bin/vim.tiny`" dato che supporta l'evidenziazione della sintassi.

| Suggerimento
Molti programmi usano la variabile d'ambiente "`$EDITOR`" o "`$VISUAL`" per decidere quale editor usare (vedereSezione 1.3.5, «L'editor interno di MC» e Sezione 9.4.11, «Personalizzare i programmi da avviare». Per coerenza, in un sistema Debian, impostare queste variabili a "`/usr/bin/editor`". (Storicamente "`$EDITOR`" era "`ed`" e "`$VISUAL`" era "`vi`".)

### 1.4.8. Usare vim

vim(1) recente si avvia con la sana opzione "`nocompatible`" e entra nella modalità `NORMAL`.[1]

Tabella 1.16. Elenco di combinazioni di tasti base di Vim

modalità | Combinazione di tasti | azione
--- | --- | ---
`NORMALE` | `:help|only` | visualizza il file di aiuto
`NORMALE` | `:e nomefile.ext` | apre un nuovo buffer per modificare `nomefile.ext`
`NORMALE` | `:w` | sovrascrive il buffer corrente sul file originale
`NORMALE` | `:w nomefile.ext` | scrive il buffer corrente su `nomefile.ext`
`NORMALE` | `:q` | esce da `vim`
`NORMALE` | `:q!` | forza l'uscita da `vim`
`NORMALE` | `:only` | chiude tutte le altre finestre staccate aperte
`NORMALE` | `:set nocompatible?` | controlla se `vim` è nella sana modalità `nocompatible`
`NORMALE` | `:set nocompatible` | imposta `vim` nella sana modalità `nocompatible`
`NORMALE` | `i` | entra nella modalità `INSERT`
`NORMALE` | `R` | entra nella modalità `REPLACE`
`NORMALE` | `v` | entra nella modalità `VISUAL`
`NORMALE` | `V` | entra nella modalità `VISUAL` a righe
`NORMALE` | Ctrl-`V` | entra nella modalità `VISUAL` a blocchi
tranne `TERMINAL-JOB` | `ESC`-key | entra nella modalità `NORMAL`
`NORMALE` | `:term` | entra nella modalità `TERMINAL-JOB`
`TERMINAL-NORMAL` | `i` | entra nella modalità `TERMINAL-JOB`
`TERMINAL-JOB` | Ctrl-`W` `N` (o Ctrl-`\` Ctrl-`N`) | entra nella modalità `TERMINAL-NORMAL`
`TERMINAL-JOB` | Ctrl-`W` `:` | entra nella `Ex`-mode nella modalità `TERMINAL-NORMAL`

Usare il programma "`vimtutor`" per imparare ad usare `vim` attraverso un corso tutorial interattivo.

Il programma `vim` cambia il suo comportamento in risposta ai tasti premuti in base alla modalità (mode). La digitazione con i tasti nel buffer è fatta soprattutto in modalità `INSERT` e in modalità `REPLACE`. Spostare il cursore viene fatto soprattutto in modalità `NORMAL`. La selezione interattiva viene fatta in modalità `VISUAL`. Se si digita "`:`" in modalità `NORMAL` si cambia la sua modalità in `Ex`-mode. `Ex`-mode accetta comandi.

| Suggerimento
Vim viene distribuito con il pacchetto Netrw. Netrw supporta lettura e scrittura di file, navigazione di directory in una rete e navigazione locale! Provare Netrw con "`vim .`" (un punto come argomento) e leggere il suo manuale con "`:help netrw`".

Per la configurazione avanzata di `vim`, vedere Sezione 9.2, «Personalizzare vim».

### 1.4.9. Registrare le attività della shell

L'output dei comandi di shell può scorrere fuori dallo schermo e potrebbe essere perduto per sempre. È buona norma registrare le attività di shell in un file in modo da poterle riguardare in seguito. Questo tipo di registro è essenziale quando si fa una qualsiasi attività di amministrazione del sistema.

| Suggerimento
Il nuovo Vim (versione>=8.2) può essere utilizzato per registrare in modo pulito le attività di shell usando la modalità `TERMINAL-JOB`. Vedere Sezione 1.4.8, «Usare vim».

Il metodo base per registrare l'attività di shell è di eseguirla sotto script(1).

Per esempio, provare a fare quanto segue.

    $ script
    Script started, file is typescript

Eseguire qualsiasi comando di shell sotto `script`.

Premere `Ctrl-D` per uscire da `script`.

    $ vim typescript

Vedere Sezione 9.1.1, «Registrare le attività della shell in modo pulito».

### 1.4.10. Comandi Unix di base

È bene imparare i comandi Unix di base. Il termine "Unix" è qui usato in senso lato; ogni SO clone di Unix offre di solito comandi equivalenti. Il sistema Debian non fa eccezione. Non ci si preoccupi se, al momento, alcuni comandi non funzionano come si vorrebbe. Se si usa `alias` nella shell, i corrispondenti output dei comandi sono diversi. Questi esempi non sono pensati per essere eseguiti necessariamente in questo ordine.

Provare tutti i comandi seguenti da un account utente non privilegiato.

Tabella 1.17. Elenco di comandi Unix di base

comando | descrizione
--- | ---
`pwd` | mostra il nome della directory attuale/di lavoro
`whoami` | mostra il nome dell'utente attuale
`id` | mostra l'identità dell'utente attuale (nome, uid, gid e gruppi associati)
`file pippo` | mostra che tipo di file sia il file "`pippo`"
`type -p nomecomando` | mostra la posizione del file del comando "`nomecomando`"
`which nomecomando` | " "
`type nomecomando` | mostra informazioni sul comando "`nomecomando`"
`apropos parola-chiave` | trova comandi riguardanti "`parola-chiave`"
`man -k parola-chiave` | " "
`whatis nomecomando` | mostra una spiegazione di una riga sul comando "`nomecomando`"
`man -a nomecomando` | mostra una spiegazione del comando "`nomecomando`" (in stile Unix)
`info nomecomando` | mostra una spiegazione piuttosto lunga del comando "`nomecomando`" (in stile GNU)
`ls` | elenca il contenuto di directory (non i file punto e le directory)
`ls -a` | elenca il contenuto di directory (tutti i file e directory)
`ls -A` | elenca il contenuto di directory (quasi tutti i file e directory, cioè salta "`..`" e "`.`")
`ls -la` | elenca tutto il contenuto di directory con informazioni dettagliate
`ls -lai` | elenca tutto il contenuto di directory con numeri di inode e informazioni dettagliate
`ls -d` | elenca tutte le directory dentro la directory attuale
`tree` | mostra il contenuto in forma di albero
`lsof pippo` | mostra lo stato aperto per il file "`pippo`"
`lsof -p pid` | mostra i file aperti dal processo con ID "`pid`"
`mkdir pippo` | crea una nuova directory "`pippo`" nella directory attuale
`rmdir pippo` | rimuove la directory "`pippo`" nella directory attuale
`cd pippo` | cambia directory spostandosi nella directory "`pippo`" nella directory attuale o in una directory elencata nella variabile "`$CDPATH`"
`cd /` | cambia directory spostandosi nella directory radice
`cd` | cambia directory spostandosi nella directory home dell'utente
`cd /pippo` | cambia directory spostandosi nella directory con percorso assoluto "`/pippo`"
`cd ..` | cambia directory spostandosi nella directory genitore
`cd ~pippo` | cambia directory spostandosi nella directory home dell'utente "`pippo`"
`cd -` | cambia directory spostandosi nella directory precedente
`</etc/motd pager` | mostra il contenuto di "`/etc/motd`" usando il paginatore predefinito
`touch filediprova` | crea un file "`filediprova`" vuoto
`cp pippo pluto` | copia un file "`pippo`" esistente in un nuovo file "`pluto`"
`rm filediprova` | rimuove il file "`filediprova`"
`mv pippo pluto` | rinomina un file "`pippo`" esistente con il nuovo nome "`pluto`" ("`pluto`" non deve esistere)
`mv pippo pluto` | muove un file "`pippo`" esistente nella nuova posizione "`pluto/pippo`" (la directory "`pluto`" deve esistere)
`mv pippo pluto/paperino` | muove un file "`pippo`" esistente in una nuova posizione con il nuovo nome "`pluto/paperino`" (la directory "`pluto`" deve esistere ma non deve esistere "`bar/baz`")
`chmod 600 pippo` | fa sì che il file "`pippo`" esistente sia non leggibile e non scrivibile da altri (e non eseguibile per nessuno)
`chmod 644 pippo` | fa sì che il file "`pippo`" esistente sia leggibile ma non scrivibile da altri (e non eseguibile per nessuno)
`chmod 755 pippo` | fa sì che il file "`pippo`" esistente sia leggibile ma non scrivibile da altri (ed eseguibile per tutti)
`find . -name modello` | trova nomi di file corrispondenti al "`modello`" di shell (lento)
`locate -d . modello` | trova nomi di file corrispondenti al "`pattern`" di shell (più veloce, usa un database generato regolarmente)
`grep -e "modello" *.html` | trova un "`modello`" in tutti i file nella directory attuale che terminano con "`.html`" e mostra tutte le corrispondenze
`top` | mostra informazioni sui processi a tutto schermo, digitare "`q`" per uscire
`ps aux | pager` | mostra informazioni su tutti i processi in esecuzione usando output in stile BSD
`ps -ef | pager` | mostra informazioni su tutti i processi in esecuzione usando output in stile system V Unix
`ps aux | grep -e "[e]xim4*"` | mostra tutti i processi che stanno eseguendo "`exim`" e "`exim4`"
`ps axf | pager` | mostra informazioni su tutti i processi in esecuzione usando output in ASCII art
`kill 1234` | uccide un processo identificato dall'ID "1234"
`gzip pippo` | comprime `pippo`" per creare "`pippo.gz`", usando la codifica Lempel-Ziv (LZ77)
`gunzip pippo.gz` | decomprime "`pippo.gz`" per creare "`pippo`"
`bzip2 pippo` | comprime "`pippo`" per creare "`pippo.bz2`", usando l'algoritmo Burrows-Wheeler per la compressione di testo con ordinamento di blocchi e la codifica Huffman (compressione migliore di `gzip`)
`bunzip2 pippo.bz2` | decomprime "`pippo.bz2`" per creare "`pippo`"
`xz pippo` | comprime "`pippo`" per creare "`pippo.xz`", usando l'algoritmo Lempel–Ziv–Markov chain (compressione migliore di `bzip2`)
`unxz pippo.xz` | decomprime "`pippo.xz`" per creare "`pippo`"
`tar -xvf pippo.tar` | estrae i file dall'archivio "`pippo.tar`"
`tar -xvzf pippo.tar.gz` | estrae file dall'archivio "`pippo.tar.gz`" compresso con gzip
`tar -xvjf pippo.tar.bz2` | estrae file dall'archivio "`pippo.tar.bz2`"
`tar -xvJf pippo.tar.xz` | estrae file dall'archivio "`pippo.tar.xz`"
`tar -cvf pippo.tar pluto/` | archivia i contenuti della directory "`pluto/`" nell'archivio "`pippo.tar`"
`tar -cvzf pippo.tar.gz pluto/` | archivia i contenuti della directory "`pluto/`" nell'archivio compresso "`pippo.tar.gz`"
`tar -cvjf pippo.tar.bz2 pluto/` | archivia i contenuti della directory "`plutor/`" nell'archivio "`pippo.tar.bz2`"
`tar -cvJf pippo.tar.xz pluto/` | archivia i contenuti della directory "`plutor/`" nell'archivio "`pippo.tar.xz`"
`zcat README.gz | pager` | mostra i contenuti del file compresso "`README.gz`" usando il paginatore predefinito
`zcat README.gz > pippo` | crea un file "`pippo` con i contenuti di "`README.gz`" decompressi
`zcat README.gz >> pippo` | aggiunge i contenuti di "`README.gz`" decompressi in coda al file "`pippo`" (se il file non esiste, lo crea)

| Nota

Unix tradizionalmente nasconde i nomi di file che iniziano con "`.`". Sono tradizionalmente file contenenti informazioni di configurazione e preferenze dell'utente.

Per il comando `cd` vedere builtins(7).

Il paginatore predefinito del sistema di base di Debian è more(1) che non ha lo scorrimento all'indietro. Installando il pacchetto `less`, con la riga di comando "`apt-get install less`", less(1) diventa il paginatore predefinito e si può così scorrere il testo all'indietro usando i tasti freccia.

I caratteri "`[`" e "`]`" nella espressione regolare del comando "`ps aux | grep -e "[e]xim4*"`" sopra citato, permettono a `grep` di evitare di trovare corrispondenza con sé stesso. La parte "`4*`" nella espressione regolare significa 0 o più ripetizioni del carattere "`4`" e perciò permette a `grep` di trovare corrispondenza sia con "`exim`" sia con "`exim4`". Sebbene il carattere "`*`" sia usato nei nomi di file con metacaratteri della shell e nelle espressioni regolari, il suo significato è diverso nei due casi. Si possono imparare le espressioni regolari da grep(1).

Come esercizio, esplorare le directory e dare un'occhiata al sistema usando i comandi citati sopra. Se si hanno domande su uno qualsiasi dei comandi in console, assicurarsi di leggere la pagina di manuale.

Per esempio, provare a fare quanto segue.

    $ man man
    $ man bash
    $ man builtins
    $ man grep
    $ man ls

Può essere un po' difficile abituarsi allo stile delle pagine man perché sono piuttosto concise, in particolar modo le più vecchie e tradizionali. Una volta che ci si fa la mano, però, si apprezza la loro concisione.

Notare che molti comandi in stile Unix, inclusi quelli da GNU e BSD, mostrano una breve informazione di aiuto se li si invoca in uno dei modi seguenti (o in alcuni casi se lo si fa senza usare opzioni).

    $ commandname --help
    $ commandname -h

## 1.5. Il semplice comando di shell

Ora si ha un'idea di come usare il sistema Debian; è tempo di dare uno sguardo più approfondito al meccanismo di esecuzione dei comandi nel sistema Debian. Qui la realtà è stata semplificata ad uso del principiante. Vedere bash(1) per una spiegazione esatta.

Un semplice comando è formato da una sequenza di componenti.

1. Assegnazioni di variabili (opzionale)

2. Nome del comando

3. Opzioni (opzionali)

4. Ridirezioni (opzionali, `>` , `>>` , `<` , `<<` , ecc.)

5. Operatori di controllo (opzionale, `&&` , `||` , a-capo , `;` , `&` , `(` , `)` )

### 1.5.1. Esecuzione dei comandi e variabili d'ambiente

I valori di alcune variabili d'ambiente cambiano il comportamento di alcuni comandi Unix.

I valori predefiniti delle variabili d'ambiente sono impostati inizialmente dal sistema PAM e poi alcuni di essi possono essere reimpostati da alcuni programmi applicativi.

- Il sistema PAM come `pam_env` può impostare variabili d'ambiente con `/etc/pam.conf`", "`/etc/environment`" e "`/etc/default/locale`".

- The modern GUI environment run from the user mode systemd unit (see systemd.unit(5)) sets its environment variables by a file in the "`~/.config/environment.d/`" directory.

- L'inizializzazione dei programmi specifica per l'utente può reimpostare variabili d'ambiente con "`~/.profile`", "`~/.bash_profile`" e "`~/.bashrc`".

### 1.5.2. La variabile "`$LANG`"

La localizzazione predefinita è definita nella variabile d'ambiente "`$LANG`" ed è configurata nella forma "`LANG=xx_YY.UTF-8`" dall'installatore o dalla successiva configurazione della GUI, es. "Impostazioni" → "Regione e lingua" → "Lingua" / "Formati" per GNOME.

| Nota
Io raccomando di configurare l'ambiente di sistema usando per il momento solo la variabile "`$LANG`" e di tenersi alla larga dalle variabili "`$LC_*`" a meno che non sia strettamente necessario.

Il valore completo di localizzazione impostato nella variabile "`$LANG`" consiste di 3 parti: "`xx_YY.ZZZZ`".

Tabella 1.18. Le 3 parti del valore di localizzazione

valore di localizzazione | significato
--- | ---
`xx` | codice ISO 639 della lingua (in minuscole), come "en"
`YY` | codice ISO 3166 del paese (in maiuscole) come "US"
`ZZZZ` | codeset, impostato sempre ad "UTF-8"

Tabella 1.19. Elenco di localizzazioni raccomandate

localizzazione raccomandata | lingua (zona)
--- | ---
`en_US.UTF-8` | inglese (USA)
`en_GB.UTF-8` | inglese (Gran Bretagna)
`fr_FR.UTF-8` | francese (Francia)
`de_DE.UTF-8` | tedesco (Germania)
`it_IT.UTF-8` | italiano (Italia)
`es_ES.UTF-8` | spagnolo (Spagna)
`ca_ES.UTF-8` | catalano (spagna)
`sv_SE.UTF-8` | svedese (Svezia)
`pt_BR.UTF-8` | portoghese (Brasile)
`ru_RU.UTF-8` | russo (Russia)
`zh_CN.UTF-8` | cinese (Repubblica Popolare Cinese)
`zh_TW.UTF-8` | cinese (Taiwan Repubblica di Cina)
`ja_JP.UTF-8` | giapponese (Giappone)
`ko_KR.UTF-8` | coreano (Corea del Sud)
`vi_VN.UTF-8` | vietnamita (Vietnam)

Una tipica esecuzione di un comando usa una sequenza sulla riga della shell come la seguente.

    $ echo $LANG
    en_US.UTF-8
    $ date -u
    Wed 19 May 2021 03:18:43 PM UTC
    $ LANG=fr_FR.UTF-8 date -u
    mer. 19 mai 2021 15:19:02 UTC

In questo caso il programma date(1) viene eseguito con differenti valori di localizzazione.

- Per il primo comando "`$LANG`" è impostata al valore di localizzazione predefinito di sistema: "`en_US.UTF-8`".

- Per il secondo comando "`$LANG`" è impostata al valore di localizzazione UTF-8 francese: `fr_FR.UTF-8`".

La maggior parte delle invocazioni di comandi non è solitamente preceduta da definizioni di variabili d'ambiente. In alternativa all'esempio precedente, si può eseguire quanto segue.

    $ LANG=fr_FR.UTF-8
    $ date -u
    mer. 19 mai 2021 15:19:24 UTC

| Suggerimento
Quando si segnala un bug, è una buona idea, se si usa un ambiente non inglese, eseguire e controllare il comando nella localizzazione "`en_US.UTF-8`".

Per dettagli più specifici sulla configurazione della localizzazione vedere Sezione 8.1, «La localizzazione».

### 1.5.3. La variabile "`$PATH`"

Quando si digita un comando nella shell, questa cerca il comando nelle directory nell'elenco contenuto nella variabile d'ambiente "`$PATH`". Il valore della variabile d'ambiente "`$PATH`" è anche chiamato percorso di ricerca della shell.

In una installazione Debian standard, la variabile d'ambiente "`$PATH`" degli account utente può non includere "`/usr/sbin`" e "`/usr/sbin`". Il comando `ifconfig`, per esempio, deve essere eseguito con il percorso completo, come in "`/usr/sbin/ifconfig`". (Il comando simile `ip` si trova in "`/usr/bin`".)

Si può modificare la variabile d'ambiente "`$PATH`" della shell Bash tramite il file "`~/.bash_profile`" o "`~/.bashrc`".

### 1.5.4. La variabile "`$HOME`"

Molti comandi memorizzano una configurazione specifica per l'utente nella directory home e cambiano il loro comportamento in base al suo contenuto. La directory home è identificata dalla variabile d'ambiente "`$HOME`".

Tabella 1.20. Elenco di valori di "`$HOME`"

valore di "`$HOME`" | situazione di esecuzione del programma
--- | ---
`/` | programma eseguito da processo init (demone)
`/root` | programma eseguito dalla normale shell di root
`/home/utente_normale` | programma eseguito dalla shell di un utente normale
`/home/utente_normale` | programma eseguito dal menu del desktop grafico di un utente normale
`/home/utente_normale` | programma eseguito come root con "`sudo programma`"
`/root` | programma eseguito come root con "`sudo -H programma`"

| Suggerimento
La shell espande "`~/` nella directory home dell'utente attuale, cioè "`$HOME/`". La shell espande "`~pippo/`" nella directory home di `pippo`, cioè "`/home/pippo/`".

Vedere Sezione 12.1.5, «Variabile d'ambiente della shell» se `$HOME` non è disponibile per il proprio programma.

### 1.5.5. Opzioni della riga di comando

Alcuni comandi accettano argomenti. Gli argomenti che iniziano con "`-`" o "`--`" sono chiamati opzioni e controllano il comportamento del comando.

    $ date
    Thu 20 May 2021 01:08:08 AM JST
    $ date -R
    Thu, 20 May 2021 01:08:12 +0900

In questo caso l'opzione "`-R`" sulla riga di comando cambia il comportamento di date(1) producendo in output la data in una stringa conforme alla RFC2822.

### 1.5.6. Glob della shell

Spesso si desidera che un comando abbia effetto su un gruppo di file senza dover digitarli tutti. I modelli di espansione dei nomi di file che usano i glob della shell, a volte detti metacaratteri o caratteri jolly, facilitano questo compito.

Tabella 1.21. Modelli di glob della shell

modello di glob della shell | descrizione della regola di corrispondenza
--- | ---
`*` | nome file (segmento) che non inizia con "`.`"
`.*` | nome file (segmento) che inizia con "`.`"
`?` | esattamente un carattere
`[…]` | esattamente un carattere tra quelli racchiusi tra le parentesi quadre
`[a-z]` | esattamente un carattere che sia un carattere compreso tra "`a`" e "`z`"
`[^…]` | esattamente un carattere che non sia uno di quelli racchiusi tra parentesi quadre (non contando "`^`")

Per esempio, provare a fare quanto segue.

    $ mkdir junk; cd junk; touch 1.txt 2.txt 3.c 4.h .5.txt ..6.txt
    $ echo *.txt
    1.txt 2.txt
    $ echo *
    1.txt 2.txt 3.c 4.h
    $ echo *.[hc]
    3.c 4.h
    $ echo .*
    . .. .5.txt ..6.txt
    $ echo .*[^.]*
    .5.txt ..6.txt
    $ echo [^1-3]*
    4.h
    $ cd ..; rm -rf junk

Vedere glob(7).

| Nota
A differenza della normale espansione dei nomi della shell, il modello shell "`*`" cercato dal comando find(1) con la ricerca "`-name`" ecc., trova corrispondenza anche con nomi di file che iniziano con "`.`". (Nuova funzionalità POSIX.)

| Nota
Si può manipolare il comportamento di BASH in relazione ai modelli di glob usando le sue opzioni shopt incorporate come "`dotglob`", "`noglob`", "`nocaseglob`", "`nullglob`", "`extglob`", ecc. Vedere bash(1).

### 1.5.7. Valore restituito dal comando

Ogni comando restituisce il suo stato di uscita (variabile "`$?`") come valore restituito.

Tabella 1.22. Codici di uscita dei comandi

stato di uscita del comando | valore numerico restituito | valore logico restituito
--- | --- | ---
successo | zero, 0 | VERO
errore | non-zero, -1 | FALSO

Per esempio provare quanto segue.

    $ [ 1 = 1 ] ; echo $?
    0
    $ [ 1 = 2 ] ; echo $?
    1

| Nota
Notare che, nel contesto logico della shell, il successo è trattato come il valore logico VERO che ha valore numerico 0 (zero). Questo è in qualche modo non intuitivo ed è bene rimarcarlo.

### 1.5.8. Sequenze tipiche di comandi e ridirezione della shell

È bene cercare di ricordare i seguenti idiomi per comandi di shell che vengono digitati sulla stessa riga come parte del comando di shell.

Tabella 1.23. Idiomi per comandi di shell

idioma per comando | descrizione
--- | ---
`comando &` | esegue `comando` sullo sfondo in una sotto-shell
`comando1 | comando2` | invia tramite pipe lo standard output di `comando1` allo standard input di `comando2` (esecuzione concorrente)
`comando1 2>&1 | comando2` | invia tramite pipe sia lo standard output sia lo standard error di `comando1` allo standard input di `comando2` (esecuzione concorrente)
`comando1 ; comando2` | esegue `comando1` e `comando2` in sequenza
`comando1 && comando2` | esegue `comando1`; se ha successo, esegue `comando2` in sequenza (restituisce lo stato di successo se sia `comando1` sia `comando2` hanno successo)
`comando1 || comando2` | esegue `comando1`; se non ha successo, esegue `comando2` in sequenza (restituisce lo stato di successo se `comando1` o `comando2` ha successo)
`comando > pippo` | ridirige lo standard output di `comando` al file "`pippo`" (sovrascrivendolo)
`comando 2> pippo` | ridirige lo standard error di `comando` al file "`pippo`" (sovrascrivendolo)
`comando >> pippo` | ridirige lo standard output di `comando` al file "`pippo`" (aggiungendo in coda)
`comando 2>> pippo` | ridirige lo standard error di `comando` al file "`pippo`" (aggiungendo in coda)
`comando > pippo 2>&1` | ridirige sia lo standard output sia lo standard error di `comando` al file `pippo`
`comando < pippo` | usa come standard input di `comando` il file "`pippo`"
`comando << delimitatore` | usa come standard input di `comando` le righe che seguono fino a che non viene incontrato il testo "`delimitatore`" (inserire un documento)
`comando <<- delimitatore` | usa come standard input di `comando` le righe che seguono fino a che non viene incontrato il testo "`delimitatore`"; i caratteri di tabulazione iniziali vengono eliminate dal testo (inserire un documento)

Il sistema Debian è un sistema multi-tasking. I compiti sullo sfondo permettono agli utenti di eseguire più programmi in una singola shell. La gestione dei processi sullo sfondo coinvolge i comandi interni della shell `jobs`, `fg`, `bg` e `kill`. Leggere le sezioni "SIGNALS" e "JOB CONTROL" di bash(1) e builtins(1).

Per esempio, provare a fare quanto segue.

    $ </etc/motd pager

    $ pager </etc/motd

    $ pager /etc/motd

    $ cat /etc/motd | pager

Benché tutti i 4 esempi di ridirezione della shell mostrino la stessa cosa, l'ultimo esempio esegue un comando `cat` aggiuntivo e spreca risorse senza motivo.

La shell permette di aprire file usando il comando interno `exec`con un descrittore di file arbitrario.

    $ echo Hello >foo
    $ exec 3<foo 4>bar  # open files
    $ cat <&3 >&4       # redirect stdin to 3, stdout to 4
    $ exec 3<&- 4>&-    # close files
    $ cat bar
    Hello

I descrittori di file 0-2 sono predefiniti.

Tabella 1.24. Descrittori di file predefiniti

device | descrizione | descrittore del file
--- | --- | ---
`stdin` | standard input | 0
`stdout` | standard output | 1
`stderr` | standard error | 2

### 1.5.9. Alias di comandi

Si possono impostare alias per i comandi usati di frequente.

Per esempio, provare a fare quanto segue.

    $ alias la='ls -la'

Ora "`la`" funziona da scorciatoia per "`ls -la`" che elenca tutti i file nel formato di elencazione esteso.

Si possono elencare tutti gli alias esistenti con `alias` (vedere la sezione "SHELL BUILTIN COMMANDS" in bash(1)).

    $ alias
    ...
    alias la='ls -la'

Si può identificare il percorso esatto o l'identità di un comando con `type` (vedere la sezione "SHELL BUILTIN COMMANDS") di bash(1)).

Per esempio, provare a fare quanto segue.

    $ type ls
    ls is hashed (/bin/ls)
    $ type la
    la is aliased to ls -la
    $ type echo
    echo is a shell builtin
    $ type file
    file is /usr/bin/file

In questo caso `ls` era stato cercato di recente mentre "`file`" no, percio "`ls`" risulta "hashed", cioè la shell ha un record interno per un accesso veloce alla posizione del comando "`ls`".

| Suggerimento
Vedere Sezione 9.3.6, «Comandi colorati».

## 1.6. Elaborazione di testo stile Unix

Nell'ambiente di lavoro Unix, l'elaborazione del testo viene fatta instradando il testo tramite pipe attraverso catene di strumenti standard per l'elaborazione del testo. Questa è stata un'altra fondamentale innovazione di Unix.

### 1.6.1. Strumenti Unix per il testo

Ci sono alcuni strumenti di elaborazione del testo che sono usati molto spesso in un sistema *nix.

- Senza l'uso di alcuna espressione regolare:

  - cat(1) concatena file e produce in output il contenuto totale.

  - tac(1) concatena file e produce l'output in senso inverso.

  - cut(1) seleziona parti di righe e le produce in output.

  - head(1) produce in output la prima parte di file.

  - tail(1) produce in output l'ultima parte di file.

  - sort(1) ordina righe in file di testo.

  - uniq(1) rimuove righe duplicate da un file ordinato.

  - tr(1) trasforma o elimina caratteri.

  - diff(1) paragona file riga per riga.

- Con espressioni regolari di base (BRE) viene usato in modo predefinito:

  - ed(1) è un primitivo editor di riga.

  - sed(1) è un editor di flussi.

  - grep(1) trova corrispondenze di testo con modelli.

  - vim(1) è un editor a schermo.

  - emacs(1) è un editor a schermo (con BRE un po' estese)

- Con l'uso di espressioni regolari estese (ERE):

  - awk(1) fa semplici elaborazioni di testo.

  - egrep(1) trova corrispondenze di testo con modelli.

  - `tcl`(3tcl) può fare ogni elaborazione di testo immaginabile: vedere re_syntax(3). Spesso usato con `tk`(3tk).

  - perl(1) può fare ogni elaborazione di testo immaginabile. Vedere perlre(1).

  - pcre2grep(1) dal pacchetto `pcre2-util` trova corrispondenze di testo con modelli PCRE (Perl Compatible Regular Expressions).

  - python(1) con il modulo `re` può fare ogni elaborazione di testo immaginabile. Vedere "`/usr/share/doc/python/html/index.html`".

Se non si è sicuri di cosa facciano esattamente questi comandi, usare "`man comando`" per scoprirlo.

| Nota
Il criterio di ordinamento e le espressioni di intervalli dipendono dalla localizzazione. Se si desidera ottenere il comportamento tradizionale di un comando, usare la localizzazione C o C.UTF-8 invece delle normali UTF-8 (vedere Sezione 8.1, «La localizzazione»).

| Nota
Le espressioni regolari Perl (perlre(1)), le PCRE (Perl Compatible Regular Expressions) e le espressioni regolari Python fornite dal modulo `re` hanno molte estensioni comuni delle normali ERE.

### 1.6.2. Espressioni regolari

Le espressioni regolari sono usate in molti strumenti di elaborazione del testo. Sono analoghe ai modelli di glob della shell, ma sono più complesse e potenti.

Una espressione regolare descrive il modello a cui trovare corrispondenza ed è composta da caratteri di testo e metacaratteri.

Un metacarattere è semplicemente un carattere con un significato speciale. Ci sono 2 stili principali, BRE e ERE, a seconda degli strumenti di testo descritti in precedenza.

Tabella 1.25. Metacaratteri per BRE e ERE

BRE | ERE | descrizione della espressione regolare
--- | --- | ---
`\ . [ ] ^ $ *` | `\ . [ ] ^ $ *` | metacaratteri comuni
`\+ \? \( \) \{ \} \|` |  | metacaratteri protetti dal carattere "`\`" di escape solo di BRE
| `+ ? ( ) { } |` | metacaratteri non protetti dal carattere "`\`" di escape solo di ERE
`c` | `c` | corrisponde al non metacarattere "`c`"
`\c` | `\c` | corrisponde al carattere letterale "`c`" anche se "`c`" è in sé stesso un metacarattere
`.` | `.` | corrisponde a qualsiasi carattere incluso il carattere di a capo
`^` | `^` | posizione all'inizio di una stringa
`$` | `$` | posizione alla fine di una stringa
`\<` | `\<` | posizione all'inizio di una parola
`\>` | `\>` | posizione alla fine di una parola
`[abc…]` | `[abc…]` | corrisponde ad ogni carattere in "`abc...`"
`[^abc…]` | `[^abc…]` | corrisponde ad ogni carattere eccetto a quelli in "`abc...`"
`r*` | `r*` | corrisponde a zero o più occorrenze della espressione regolare identificata da "`r`"
`r\+` | `r+` | corrisponde ad una o più occorrenza della espressione regolare identificata da "`r`"
`r\?` | `r?` | corrisponde a zero o una occorrenza dell'espressione regolare identificata da "`r`"
`r1\|r2` | `r1|r2` | corrisponde ad una occorrenza della espressione regolare identificata da "`r1`" o "`r2`"
`\(r1\|r2\)` | `(r1|r2)` | corrisponde ad una occorrenza dell'espressione regolare identificata da "`r1`" o "`r2`" e la tratta come una espressione regolare tra parentesi

Le espressioni regolari di `emacs` sono fondamentalmente BRE, ma sono state estese per trattare "`+`" e "`?`" come i metacaratteri nelle ERE. Perciò, nelle espressioni regolari di `emacs`, non è necessario proteggerli con il carattere di escape "`\`".

Per effettuare ricerche di testo usando espressioni regolari si può usare grep(1).

Per esempio, provare a fare quanto segue.

    $ egrep 'GNU.*LICENSE|Yoyodyne' /usr/share/common-licenses/GPL
    GNU GENERAL PUBLIC LICENSE
    GNU GENERAL PUBLIC LICENSE
    Yoyodyne, Inc., hereby disclaims all copyright interest in the program

| Suggerimento
Vedere Sezione 9.3.6, «Comandi colorati».

### 1.6.3. Espressioni di sostituzione

Per le espressioni di sostituzione alcuni caratteri hanno un significato particolare.

Tabella 1.26. L'espressione di sostituzione

espressione di sostituzione | descrizione del testo che sostituirà l'espressione di sostituzione
--- | ---
`&` | ciò che ha ha avuto corrispondenza con l'espressione regolare (usare `\&` in `emacs`)
`\n` | ciò che ha avuto corrispondenza con la n-esima espressione regolare tra parentesi ("n" è un numero)

Per le stringhe di sostituzione Perl viene usato «$&» invece di «&» e «$n» invece di «\n».

Per esempio, provare a fare quanto segue.

    $ echo zzz1abc2efg3hij4 | \
    sed -e 's/\(1[a-z]*\)[0-9]*\(.*\)$/=&=/'
    zzz=1abc2efg3hij4=
    $ echo zzz1abc2efg3hij4 | \
    sed -E -e 's/(1[a-z]*)[0-9]*(.*)$/=&=/'
    zzz=1abc2efg3hij4=
    $ echo zzz1abc2efg3hij4 | \
    perl -pe 's/(1[a-z]*)[0-9]*(.*)$/=$&=/'
    zzz=1abc2efg3hij4=
    $ echo zzz1abc2efg3hij4 | \
    sed -e 's/\(1[a-z]*\)[0-9]*\(.*\)$/\2===\1/'
    zzzefg3hij4===1abc
    $ echo zzz1abc2efg3hij4 | \
    sed -E -e 's/(1[a-z]*)[0-9]*(.*)$/\2===\1/'
    zzzefg3hij4===1abc
    $ echo zzz1abc2efg3hij4 | \
    perl -pe 's/(1[a-z]*)[0-9]*(.*)$/$2===$1/'
    zzzefg3hij4===1abc

In questo esempio si faccia particolare attenzione allo stile delle espressioni regolari tra parentesi e come le stringhe corrispondenti siano usate nel processo di sostituzione del testo dai diversi strumenti.

Queste espressioni regolari possono essere usate per spostare il cursore e per fare sostituzioni di testo anche in alcuni editor.

La barra inversa, "`\`" alla fine della prima riga nella riga di comando di shell protegge il carattere di a capo rendendolo uno spazio e continuando l'input della riga di comando di shell nella riga successiva.

Leggere tutte le pagine man relative per imparare l'uso di questi comandi.

### 1.6.4. Sostituzione globale con espressioni regolari

Il comando ed(1) può sostituire tutte le occorrenze di "`DA_REGEX`" con "`A_TESTO`" in "`file`".

    $ ed file <<EOF
    ,s/FROM_REGEX/TO_TEXT/g
    w
    q
    EOF

Il comando sed(1) può sostituire tutte le occorrenze di "`DA_REGEX`" con "`A_TESTO`" in "`file`".

    $ sed -i -e 's/FROM_REGEX/TO_TEXT/g' file

Il comando vim(1) può sostituire tutte le occorrenze di "`DA_REGEX`" with "`A_TESTO`" in "`file`" usando il comando ex(1).

    $ vim '+%s/FROM_REGEX/TO_TEXT/gc' '+update' '+q' file

| Suggerimento
Il modificatore "`c`" nell'esempio soprastante assicura che venga chiesta la conferma interattiva per ciascuna sostituzione.

Si possono elaborare file multipli ("`file1`", "`file2`" e "`file3`") in modo simile con vim(1) o perl(1).

    $ vim '+argdo %s/FROM_REGEX/TO_TEXT/gce|update' '+q' file1 file2 file3

| Suggerimento
Il modificatore "`e`" nell'esempio soprastante evita che un errore di nessuna corrispondenza trovata ("No match") rompa il processo.

    $ perl -i -p -e 's/FROM_REGEX/TO_TEXT/g;' file1 file2 file3

Nell'esempio perl(1), "`-i`" è per la modificain-situ di ciascun file interessato, e "`-p`" è perreiterare implicitamente il comando su tutti i file specificati.

| Suggerimento
L'uso dell'opzione "`-i.bak`" invece di "`-i`" preserva una copia del file originale aggiungendo il suffisso "`.bak`" al suo nome file. Questo permette di ripristinare le cose più facilmente in caso di errori in sostituzioni complesse.

| Nota
ed(1) e vim(1) usano BRE; perl(1) usa ERE.

### 1.6.5. Estrarre dati da file con tabelle di testo

Considerare per esempio un file ti testo chiamato "`DPL`" in cui sono elencati, in un formato separato da spazi, alcuni nomi di leader del progetto Debian pre-2004 e la data della loro installazione.

    Ian     Murdock   August  1993
    Bruce   Perens    April   1996
    Ian     Jackson   January 1998
    Wichert Akkerman  January 1999
    Ben     Collins   April   2001
    Bdale   Garbee    April   2002
    Martin  Michlmayr March   2003

| Suggerimento
Vedere "Una breve storia di Debian" per la storia della Guida del progetto Debian aggiornata.

Awk viene usato spesso per estrarre dati da questo tipo di file.

Per esempio, provare a fare quanto segue.

    $ awk '{ print $3 }' <DPL                   # month started
    August
    April
    January
    January
    April
    April
    March
    $ awk '($1=="Ian") { print }' <DPL          # DPL called Ian
    Ian     Murdock   August  1993
    Ian     Jackson   January 1998
    $ awk '($2=="Perens") { print $3,$4 }' <DPL # When Perens started
    April 1996

Questo tipo di file può anche essere analizzato con le shell tipo Bash.

Per esempio, provare a fare quanto segue.

    $ while read first last month year; do
        echo $month
      done <DPL
    ... same output as the first Awk example

In questo caso, il comando incorporato `read` usa i caratteri in "`$IFS`" (internal field separator, separatore di campi interno) per suddividere le righe in parole.

Se si modifica "`$IFS`" in "`:`", si possono analizzare facilmente con la shell i file "`/etc/passwd`".

    $ oldIFS="$IFS"   # save old value
    $ IFS=':'
    $ while read user password uid gid rest_of_line; do
        if [ "$user" = "bozo" ]; then
          echo "$user's ID is $uid"
        fi
      done < /etc/passwd
    bozo's ID is 1000
    $ IFS="$oldIFS"   # restore old value

(Se si usa Awk per fare la stessa cosa, usare "`FS=':'`" per impostare il separatore di campi.)

IFS viene anche usato dalla shell per suddividere i risultati dell'espansione di parametri, sostituzione di comandi ed espansioni aritmetiche. Queste non avvengono all'interno delle virgolette singole o doppie. Il valore predefinito di IFS è la combinazione di spazio, tab e a capo.

Essere prudenti nell'uso di questi trucchetti di shell con IFS. Possono accadere strane cose quando la shell interpreta alcune parti dello script come suo input.

    $ IFS=":,"                        # use ":" and "," as IFS
    $ echo IFS=$IFS,   IFS="$IFS"     # echo is a Bash builtin
    IFS=  , IFS=:,
    $ date -R                         # just a command output
    Sat, 23 Aug 2003 08:30:15 +0200
    $ echo $(date -R)                 # sub shell --> input to main shell
    Sat  23 Aug 2003 08 30 36 +0200
    $ unset IFS                       # reset IFS to the default
    $ echo $(date -R)
    Sat, 23 Aug 2003 08:30:50 +0200

### 1.6.6. Frammenti di script per comandi con pipe

Gli script seguenti fanno alcune cose carine se inseriti in una pipe.

Tabella 1.27. Elenco di frammenti di script per comandi con pipe

frammento di script (digitarlo in un'unica riga) | effetto del comando
--- | ---
`find /usr -print` | trova tutti i file in "`/usr`"
`seq 1 100` | stampa da 1 a 100
`| xargs -n 1 comando` | esegue ripetutamente il comando con ogni elemento dalla pipe come argomento
`| xargs -n 1 echo` | suddivide elementi separati da spazio nella pipe su righe distinte
`| xargs echo` | unisce tutte le righe dalla pipe in una riga
`| grep -e modello_regex` | estrae dalla pipe le righe che contengono ‪modello_regex
`| grep -v -e modello_regex` | estrae dalla pipe le righe che non contengono modello_regex
`| cut -d: -f3 -` | estrae dalla il terzo campo, separato da "`:`" (file passwd, ecc.)
`| awk '{ print $3 }'` | estrae dalla pipe il terzo campo separato da spazi
`| awk -F'\t' '{ print $3 }'` | estrae dalla pipe il terzo campo separato da tabulazioni
`| col -bx` | rimuove i caratteri backspace ed espande le tabulazioni in sequenze di spazi
`| expand -` | espande le tabulazioni
`| sort| uniq` | ordina e rimuove i duplicati
`| tr 'A-Z' 'a-z'` | converte le maiuscole in minuscole
`| tr -d '\n'` | concatena le righe in un'unica riga
`| tr -d '\r'` | rimuove i caratteri di a capo
`| sed 's/^/# /'` | aggiunge "`#`" all'inizio di ogni riga
`| sed 's/\.ext//g'` | rimuove "`.ext`"
`| sed -n -e 2p` | stampa la seconda riga
`| head -n 2 -` | stampa le prime due righe
`| tail -n 2 -` | stampa le ultime due righe

Uno script di shell di una riga può operare reiteratamente su più file usando find(1) e xargs(1) per fare compiti piuttosto complicati. Vedere Sezione 10.1.5, «Esempi di invocazione per la selezione di file» e Sezione 9.4.9, «Ripetere un comando su diversi file».

Quando usare la shell in modalità interattiva diventa troppo complicato, considerare la scrittura di uno script di shell (vedere Sezione 12.1, «Script shell»).

[1] Anche il vecchio `vim` può avviarsi nella modalità "`nocompatible`" sensata se lo si avvia con l'opzione "`-N`".

Prefazione |  | Capitolo 2. Gestione dei pacchetti in Debian