Capitolo 1. Tutorial GNU/Linux

Indice

1.1. Nozioni di base sulla console
1.1.1. Il prompt di shell
1.1.2. Il prompt di shell in X
1.1.3. L'account root
1.1.4. Il prompt di shell di root
1.1.5. Strumenti di amministrazione del sistema con interfaccia utente grafica
1.1.6. Console virtuali
1.1.7. Come uscire dal prompt dei comandi
1.1.8. Come spegnere il sistema
1.1.9. Ripristinare una console funzionante
1.1.10. Suggerimenti per pacchetti aggiuntivi per i principianti
1.1.11. Un account utente extra
1.1.12. Configurazione di sudo
1.1.13. Tempo di giocare
1.2. File system stile Unix
1.2.1. Nozioni di base sui file Unix
1.2.2. Aspetti tecnici del file system
1.2.3. Permessi del file system
1.2.4. Controllo dei permessi per i file appena creati: umask
1.2.5. Permessi per gruppi di utenti (gruppi)
1.2.6. Orari
1.2.7. Collegamenti
1.2.8. Pipe con nome (FIFO)
1.2.9. Socket
1.2.10. File di device
1.2.11. File di device speciali
1.2.12. procfs e sysfs
1.2.13. tmpfs
1.3. Midnight Commander (MC)
1.3.1. Personalizzazione di MC
1.3.2. Avvio di MC
1.3.3. Gestore dei file in MC
1.3.4. Trucchetti per la riga di comando di MC
1.3.5. L'editor interno di MC
1.3.6. Il visualizzatore interno di MC
1.3.7. Funzionalità di avvio automatico di MC
1.3.8. File system FTP virtuale di MC
1.4. Ambiente di lavoro di base in stile Unix
1.4.1. La shell di login
1.4.2. Personalizzare bash
1.4.3. Associazioni di tasti speciali
1.4.4. Funzionamento del mouse in stile Unix
1.4.5. Il paginatore
1.4.6. L'editor di testo
1.4.7. Impostare un editor di testi predefinito
1.4.8. Personalizzare vim
1.4.9. Registrare le attività della shell
1.4.10. Comandi Unix di base
1.5. Il semplice comando di shell
1.5.1. Esecuzione dei comandi e variabili d'ambiente
1.5.2. La variabile "$LANG"
1.5.3. La variabile "$PATH"
1.5.4. La variabile "$HOME"
1.5.5. Opzioni della riga di comando
1.5.6. Glob della shell
1.5.7. Valore restituito dal comando
1.5.8. Sequenze tipiche di comandi e ridirezione della shell
1.5.9. Alias di comandi
1.6. Elaborazione di testo stile Unix
1.6.1. Strumenti Unix per il testo
1.6.2. Espressioni regolari
1.6.3. Espressioni di sostituzione
1.6.4. Sostituzione globale con espressioni regolari
1.6.5. Estrarre dati da file con tabelle di testo
1.6.6. Frammenti di script per comandi con pipe

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] 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.

All'avvio del sistema, se non è stato installato il Sistema X Window con un display manager come gdm3, viene presentata la schermata di login a caratteri. Supponiamo che il proprio nome host sia pippo, il prompt di login apparirà come segue.

pippo login:

Se è stato installato un ambiente GUI come GNOME o KDE, allora ci si può spostare ad un prompt di login premendo Ctrl-Alt-F1 e si può ritornare all'ambiente grafico con Alt-F7 (vedere Sezione 1.1.6, «Console virtuali» in seguito per maggiori informazioni).

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] 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 jessie/sid pippo tty1
pippo login: pinguino
Password:
Last login: Mon Sep 23 19:36:44 JST 2013 on tty3
Linux snoopy 3.11-1-amd64 #1 SMP Debian 3.11.6-2 (2013-11-01) 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.
pippo:~$

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

Se è stato installato il Sistema X Window con un display manager come gdm3 di GNOME, selezionando l'attività "Ambiente desktop" 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 sotto X avviando un programma emulatore di terminale come gnome-terminal(1), rxvt(1) o xterm(1). Nell'ambiente desktop GNOME, cliccare su "Applicazioni" → "Accessori" → "Terminale" .

Si può anche fare riferimento alla sezione Sezione 1.1.6, «Console virtuali» in seguito.

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.

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] Avvertimento

Non comunicare mai la password di root ad altri.

[Nota] 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»).

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 dell'emulatore di terminale per X, quali gnome-terminal(1), rxvt(1) o xterm(1). Vedere Sezione 1.1.4, «Il prompt di shell di root» e Sezione 7.8.5, «Eseguire client X come root».

[Avvertimento] Avvertimento

Non avviare mai il gestore di sessioni/display manager di X dall'account root inserendo root al prompt di un display manager come gdm3(1).

[Avvertimento] Avvertimento

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.

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 F1F6. 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 è nel Sistema X Window, si accedere alla console a caratteri 1 premendo i tasti Ctrl-Alt-F1, cioè premendo contemporaneamente il tasto_Ctrl_sinistro, il tasto_Alt_sinistro e il tasto_F1. Si può tornare al Sistema X Window, che di solito è in esecuzione sulla console virtuale 7, premendo Alt-F7.

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

# chvt 1

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

In alternativa, se "/etc/inittab" contiene "ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -h now" al suo interno, per spegnere si può digitare Ctrl-Alt-Canc (il tasto_Ctrl_sinistro, il tasto_Alt_sinistro e Canc sono premuti contemporaneamente). Per i dettagli vedere inittab(5).

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

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
 ...

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


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


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

# apt-get install nome_pacchetto

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 "pinguino  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 "pinguino  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] 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] Attenzione

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

[Attenzione] Attenzione

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] 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).

[Nota] Nota

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.

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.

Ecco alcune nozioni di base sui file Unix.

[Nota] 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] 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] 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.


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] Suggerimento

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

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.


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 <nuovoproprietario> pippo
# chgrp <nuovogruppo> pippo
# chmod  [ugoa][+-=][rwxXst][,...] pippo

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 /qualche/posizione/
# chown -R pippo:pluto .
# 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.


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 pippo pluto
$ chmod u=rw,go=r pippo
$ chmod 644 pluto
$ ls -l pippo pluto
-rw-r--r-- 1 pinguino pinguino 0 ott 16 21:39 pluto
-rw-r--r-- 1 pinguino pinguino 0 ott 16 21:35 pippo
[Suggerimento] 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".

Per far sì che i permessi di un gruppo vengano applicati ad un particolare utente, tale utente deve essere inserito come membro del gruppo usando "sudo vigr" per /etc/group e "sudo vigr -s" per /etc/gshadow. Per abilitare la nuova configurazione dei gruppi è necessario fare il log out e quindi di nuovo il login (oppure eseguire "exec newgrp").

[Nota] 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.)

I dispositivi hardware sono, in un sistema Debian, semplicemente un altro tipo di file. Se si hanno problemi ad accedere a dispositivi quali CD-ROM e chiavette USB da un account utente, si dovrebbe inserire quell'utente nel gruppo appropriato.

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


[Suggerimento] 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.


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.

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


[Nota] Nota

ctime non è l'orario di creazione del file.

[Nota] 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] 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 stringhe diverse con le localizzazioni non in inglese ("it_IT.UTF-8") rispetto alla vecchia ("C").

$ LANG=it_IT.UTF-8  ls -l pippo
-rw-rw-r-- 1 pinguino pinguino 0 ott 16 21:35 pippo
$ LANG=C  ls -l pippo
-rw-rw-r-- 1 pinguino pinguino 0 Oct 16 21:35 pippo
[Suggerimento] Suggerimento

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

Ci sono due metodi per associale un file "pippo" ad un diverso nome file "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 "Contenuto originale" > pluto
$ ls -li pluto
1449840 -rw-rw-r-- 1 penguin penguin 17 ott 16 21:42 pluto
$ ln pluto paper    # collegamento fisico
$ ln -s pluto pippo  # collegamento simbolico
$ ls -li pluto paper pippo
1449840 -rw-rw-r-- 2 penguin penguin 17 ott 16 21:42 paper
1450180 lrwxrwxrwx 1 penguin penguin  3 ott 16 21:47 pippo -> pluto
1449840 -rw-rw-r-- 2 penguin penguin 17 ott 16 21:42 pluto
$ rm pluto
$ echo "Nuovo contenuto" > pluto
$ ls -li pluto paper pippo
1449840 -rw-rw-r-- 1 penguin penguin 17 ott 16 21:42 paper
1450180 lrwxrwxrwx 1 penguin penguin  3 ott 16 21:47 pippo -> pluto
1450183 -rw-rw-r-- 1 penguin penguin 12 ott 16 21:48 pluto
$ cat paper
Contenuto originale
$ cat pippo
Nuovo contenuto

Il collegamento fisico può essere creato all'interno dello stesso file system e condivide uno 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] 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] 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.

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 miapipe
$ echo "hello" >miapipe & # messo sullo sfondo
[1] 8022
$ ls -l miapipe
prw-rw-r-- 1 pinguino pinguino 0 ott 16 21:49 miapipe
$ cat miapipe
hello
[1]+  Done                    echo "hello" >miapipe
$ ls miapipe
miapipe
$ rm miapipe

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] 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).

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.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-*.

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-*.

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

  • "/sbin" e "/bin"

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 nome_del_file_da_modificare
$ mcedit nome_del_file_da_modificare

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-F<n> 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.

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.

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] Nota

I buoni editor, come Vim ed Emacs, possono gestire correttamente testi UTF-8 e testi in altre codifiche esotiche. È opportuno usare l'ambiente X 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 X. Fare riferimento alla loro documentazione sui testi multibyte.

È 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.16. 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] Nota

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

[Nota] Nota

Per il comando cd vedere builtins(7).

[Nota] Nota

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.

[Nota] Nota

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).

$ <nomecomando> --help
$ <nomecomando> -h

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> , ; , & , ( , ) )

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 display manager, come gdm3, reimposta variabili d'ambiente.

  • La shell reimposta variabili d'ambiente nel suo codice di avvio in "~/.bash_profile" e "~/.bashrc".

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


Per i codici delle lingue e dei paesi, vedere le descrizioni pertinenti in "info gettext".

In un sistema Debian moderno il codeset dovrebbe essere sempre impostato a UTF-8, a meno che non si voglia specificatamente usare uno usato in passato e avendo una buona ragione e le conoscenze per farlo.

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

[Nota] Nota

"LANG=en_US" non è "LANG=C" né "LANG=en_US.UTF-8". È "LANG=en_US.ISO-8859-1" (vedere Sezione 8.4.1, «Nozioni base sulla codifica»).


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

$ date
Sun Jun  3 10:27:39 JST 2007
$ LANG=fr_FR.UTF-8 date
dimanche 3 juin 2007, 10:27:33 (UTC+0900)

In questo caso il programma date(1) viene eseguito con valori differenti della variabile d'ambiente "$LANG".

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
dimanche 3 juin 2007, 10:27:33 (UTC+0900)

Come si può vedere, l'output del comando è in questo caso influenzato dalla variabile d'ambiente per produrre output in francese. Se si desidera che una variabile d'ambiente venga ereditata da sottoprocessi, ad esempio quando si invocano script di shell, è necessario invece esportarla nel modo seguente.

$ export LANG
[Nota] Nota

Quando si usa un tipico terminale in console, la variabile d'ambiente "$LANG" è solitamente impostata per essere esportata dall'ambiente desktop. Perciò quello sopra non è veramente un buon esempio per testare l'effetto di export.

[Suggerimento] Suggerimento

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

Vedere locale(5) e locale(7) per "$LANG" e variabili d'ambiente correlate.

[Nota] Nota

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

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.


Per esempio, provare a fare quanto segue.

$ mkdir prova; cd prova; 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 prova

Vedere glob(7).

[Nota] 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] 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).

È 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.22. 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 execcon un descrittore di file arbitrario.

$ echo Hello >pippo
$ exec 3<pippo 4>pluto  # apre i file
$ cat <&3 >&4       # ridirige lo stdin in 3, lo stdout in 4
$ exec 3<&- 4>&-    # chiude i file
$ cat pluto
Hello

I descrittori di file 0-2 sono predefiniti.


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.

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

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

[Nota] 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 invece di quelle UTF-8 anteponendo al comando "LANG=C" (vedere Sezione 1.5.2, «La variabile "$LANG e Sezione 8.4, «La localizzazione»).

[Nota] 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.

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.


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

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


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 's/\(1[a-z]*\)[0-9]*\(.*\)$/\2===\1/'
zzzefg3hij4===1abc
$ echo zzz1abc2efg3hij4 | \
perl -pe 's/(1[a-z]*)[0-9]*(.*)$/$2===$1/'
zzzefg3hij4===1abc
$ echo zzz1abc2efg3hij4 | \
perl -pe 's/(1[a-z]*)[0-9]*(.*)$/=$&=/'
zzz=1abc2efg3hij4=

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.

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   Agosto  1993
Bruce   Perens    Aprile  1996
Ian     Jackson   Gennaio 1998
Wichert Akkerman  Gennaio 1999
Ben     Collins   Aprile  2001
Bdale   Garbee    Aprile  2002
Martin  Michlmayr Marzo   2003

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

Per esempio, provare a fare quanto segue.

$ awk '{ print $3 }' <DPL                   # mese di inizio
Agosto
Aprile
Gennaio
Gennaio
Aprile
Aprile
Marzo
$ awk '($1=="Ian") { print }' <DPL          # leader del progetto chiamato Ian
Ian     Murdock   Agosto  1993
Ian     Jackson   Gennaio 1998
$ awk '($2=="Perens") { print $3,$4 }' <DPL # quando ha iniziato Perens
Aprile 1996

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

Per esempio, provare a fare quanto segue.

$ while read nome cognome mese anno; do
    echo $mese
  done <DPL
... stesso output del primo esempio Awk

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".

$ vecchioIFS="$IFS"   # salva il vecchio valore
$ IFS=':'
$ while read utente password uid gid resto_della_riga; do
    if [ "$utente" = "bozo" ]; then
      echo "l'ID di $utente e' $uid"
    fi
  done < /etc/passwd
l'ID di bozo e' 1000
$ IFS="$vecchioIFS"   # ripristina il vecchio valore

(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=":,"                        # usa ":" e "," come IFS
$ echo IFS=$IFS,   IFS="$IFS"     # echo e'  un comando interno di Bash
IFS=  , IFS=:,
$ date -R                         # un output di comando qualunque
Sat, 23 Aug 2003 08:30:15 +0200
$ echo $(date -R)                 # sotto-shell --> input alla shell principale
Sat  23 Aug 2003 08 30 36 +0200
$ unset IFS                       # reimposta il valore predefinito di IFS
$ echo $(date -R)
Sat, 23 Aug 2003 08:30:50 +0200

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


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.3.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»).