%%
%% Dispense amministrazione base
%%
%% Copyright (C) 2003-2018 Simone Piccardi and Truelite Srl.
%%
%% This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
%% International License. To view a copy of this license, visit
%% \url{http://creativecommons.org/licenses/by-sa/4.0/} or send a letter to
%% Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
%% 
%% S. Piccardi Aug. 2003
%% 
%% shell.tex: la shell e i comandi
%%
\chapter{La shell e i comandi}
\label{cha:shell_commands}


\section{L'interfaccia a linea di comando}
\label{sec:shell_cli}

I sistemi Unix nascono negli anni '70, ben prima della nascita delle
interfacce grafiche, quando l'unico modo di interagire con il computer era
attraverso dei terminali, se non addirittura delle semplici telescriventi. Per
cui, anche se oggi sono disponibili delle interfacce grafiche del tutto
analoghe a quelle presenti in altri sistemi operativi nati in tempi più
recenti, l'interfaccia a riga di comando resta di fondamentale importanza,
dato che 30 anni di storia e migliaia di persone che ci hanno lavorato sopra
per migliorarla, la hanno resa l'interfaccia utente più potente e flessibile
che ci sia.


\subsection{La filosofia progettuale}
\label{sec:shell_design}

Come per il sistema, anche le caratteristiche dell'interfaccia a riga di
comando derivano da alcune scelte progettuali precise. Arnold Robbins spiega
molto chiaramente questa filosofia in un articolo riportato anche nella pagina
\textit{info} (vedi sez.~\ref{sec:documentazione}) del pacchetto dei
\texttt{coreutils} GNU. In sostanza la filosofia progettuale della shell e dei
comandi a riga di comando si può capire facendo ricorso ad una analogia, che
riprenderemo da quell'articolo.

Molte persone utilizzano un coltellino svizzero, dato che questo permette di
avere in solo oggetto un discreto insieme di attrezzi diversi: coltello,
forbici, cacciavite, seghetto, cavatappi. Però è molto difficile vedere un
professionista usare il coltellino svizzero per fare il suo lavoro. Un
professionista ha bisogno di attrezzi professionali, e un carpentiere non
costruisce una casa con un coltellino svizzero, ma con tanti attrezzi,
ciascuno dei quali è specializzato nello svolgere un compito specifico.

Le persone che hanno progettato l'interfaccia a riga di comando erano appunto
dei professionisti, che sapevano bene che anche se fare un programma unico per
tutti i compiti poteva essere attraente per l'utente finale, che deve
conoscere solo quello, in pratica questo sarebbe stato difficile da scrivere,
mantenere e soprattutto estendere. Per cui da professionisti pensarono ai
programmi come a degli attrezzi, e piuttosto che il coltellino svizzero
realizzarono l'equivalente della cassetta degli attrezzi (quella che in gergo
viene chiamata ``\textit{Unix toolbox}''), con in testa un criterio
fondamentale: che ciascun programma facesse una sola cosa, nel miglior modo
possibile.

Questa è la caratteristica fondamentale dei programmi base di un sistema
unix-like come GNU/Linux. Ogni comando è progettato per eseguire un compito
preciso. Ne abbiamo incontrati già diversi nel corso della trattazione delle
caratteristiche del sistema nel precedente capitolo: \texttt{ls} mostra la
lista dei file, \texttt{ps} la lista dei processi, \texttt{cp} copia un file,
\texttt{chmod} cambia i permessi, \texttt{man} mostra le pagine di manuale,
ecc. I comandi hanno uno scopo preciso e precise funzionalità; le opzioni sono
limitate e comunque specifiche allo scopo del comando, e sono descritte
dettagliatamente nella relativa pagina di manuale.

Il passo successivo fu quello di costruire anche un meccanismo che permettesse
di combinare insieme i vari programmi, cosicché divenisse possibile eseguire,
con una opportuna combinazione, anche dei compiti che nessuno di essi era in
grado di fare da solo. Questo aveva il grande vantaggio, rispetto
all'approccio del programma universale, di non dover attendere che l'autore
dello stesso si decidesse a programmare la funzione in più che serviva e che
non era stata prevista all'inizio.

Questo è il ruolo della \textit{shell}, cioè del programma che implementa
l'interfaccia a riga di comando; è attraverso di essa che, concatenando vari
comandi, si può costruire l'equivalente di una catena di montaggio, in cui il
risultato di un comando viene inviato al successivo, riuscendo così a
realizzare compiti complessi con grande velocità e flessibilità, e spesso a
fare anche cose che gli autori dei singoli programmi non si sarebbero neanche
immaginati.

La modalità tradizionale con cui si utilizza l'interfaccia a riga di comando è
attraverso una sessione di lavoro interattiva eseguita su un terminale. Un
tempo questo accesso avveniva con la classica procedura di collegamento al
sistema sulla console (torneremo su questo in sez.~\ref{sec:cfg_login})
dove un apposito programma, \texttt{login}, una volta autenticato l'utente,
mette in esecuzione la \textit{shell}.

Oggi, con la presenza sempre più diffusa delle interfacce grafiche e la
diffusione delle reti, si hanno molte altre modalità di accesso ad un
terminale. Ad esempio si può avere un opportuno programma, il cosiddetto
\textsl{emulatore di terminale}, che opera all'interno dell'interfaccia
grafica creando un terminale virtuale a cui si accede all'interno di una
finestra, oppure si può accedere via rete attraverso un programma di
collegamento remoto ed anche in questo caso esistono diversi programmi e
diversi protocolli di collegamento (vedremo il principale in
sez.~\ref{sec:net_ssh}). In tutti questi casi comunque, una volta predisposta
l'opportuna interfaccia di accesso, viene sempre lanciata una shell.

Si ricordi comunque che per il kernel, secondo la filosofia fondamentale di
Unix illustrata in sez.~\ref{sec:struct_base}, la shell resta un programma
come tutti gli altri; essa ha però un compito fondamentale, che è quello di
fornire l'interfaccia che permette di lanciare altri programmi.  Inoltre è
sempre la shell che permette di usufruire di tutta una serie di ulteriori
funzionalità messe a disposizione dal kernel, come il controllo di sessione
trattato in sez.~\ref{sec:struct_job_control}.

Dato che la shell è un programma come gli altri, essa può essere realizzata in
diversi modi, ed in effetti nel tempo sono state realizzate diverse shell.
Anche in questo caso ci sono stati due filoni di sviluppo, il primo deriva
dalla prima shell realizzata, la \textit{Bourne shell}, chiamata così dal nome
del suo creatore. La \textit{Bourne shell} è la shell più antica e le sue
funzionalità sono anche state standardizzate nello standard POSIX.2. Il
secondo filone nasce da un'altra shell, che usa una sintassi leggermente
diversa, con delle analogie con quella del linguaggio C, e che per questo
venne chiamata \textit{C shell}.

Ciascuno di questi due filoni ha dato vita a successive versioni di shell con
funzionalità più o meno avanzate; un breve elenco di quelle più significative
disponibili su GNU/Linux è il seguente:
\begin{itemize}
\item \textbf{\textit{Bourne shell e derivate}}.
  \begin{itemize}
  \item \textbf{La Bourne shell}. La prima shell di Unix, in genere utilizzata
    semplicemente con il comando \index{shell!\texttt{sh}}\texttt{sh}. Non
    viene praticamente più usata. In GNU/Linux è sostituita da \texttt{bash},
    che quando viene invocata come \texttt{sh} fornisce esclusivamente le
    funzionalità previste dallo standard POSIX.2, disabilitando le varie
    estensioni di cui è dotata, o da \texttt{dash}.  Sugli altri sistemi che
    rispettano lo standard POSIX.2, è di norma sostituita da \texttt{ksh}.
  \item \textbf{La Bourne-Again Shell}.  La \textit{bash} è la shell di
    riferimento del progetto GNU. Il suo nome è un gioco di parole sul nome
    della \textit{Bourne shell}, in sostanza una shell ``\textsl{rinata}''.
    Viene utilizzata con il comando \index{shell!\texttt{bash}} \texttt{bash}.
    Incorpora molte funzionalità avanzate, come la storia dei comandi (detta
    \textit{history}), l'auto-completamento dell'input sulla linea di comando
    (per comandi, nomi di file e qualunque altra cosa, date le opportune
    estensioni), editing di linea, costrutti di programmazione complessi e
    molto altro (praticamente di tutto, si vocifera sia anche in grado di fare
    il caffè).
  \item \textbf{La Korn Shell} La Korn shell (dal nome dell'autore) è stata la
    prima ad introdurre la \textit{history} (l'accesso ai comandi precedenti)
    e l'editing della linea di comando. Ha il grosso difetto che gran parte
    delle funzionalità avanzate non vengono attivate di default, per cui
    occorre un ulteriore lavoro di configurazione per utilizzarla al meglio.
    Viene utilizzata con il comando \index{shell!\texttt{ksh}} \texttt{ksh}.
    Non viene usata su GNU/Linux dato che \texttt{bash} ne ha tutte le
    caratteristiche; è però utile conoscerne l'esistenza dato che è facile
    trovarla su altri Unix.
  \item \textbf{La ash}. Una shell \emph{minimale}, realizzata in poche decine
    di kilobyte di codice sorgente. Viene utilizzata con il comando
    \index{shell!\texttt{ash}} \texttt{ash}. Ha molti comandi integrati,
    occupa poca RAM e poco spazio disco, ed ha poche funzioni (ma è conforme
    allo standard POSIX.2).  Viene usata spesso nei dischetti di installazione
    o recupero e nei sistemi embedded, può essere utile per sistemi dove si fa
    un grosso uso di script semplici perché è più veloce di \texttt{bash}.
  \item \textbf{La Z shell}. Un'altra shell avanzata. Viene utilizzata con il
    comando \index{shell!\texttt{zsh}} \texttt{zsh}. Offre praticamente le
    stesse funzioni della Korn shell, ed altre funzionalità avanzate, come il
    completamento di comandi, file e argomenti, che però trovate anche nella
    \texttt{bash}.
  \end{itemize}
  
\item \textbf{\textit{C shell e derivate}}.
  \begin{itemize}
  \item \textbf{La C shell}. Utilizza una sintassi con analogie a quella del
    linguaggio C.  Viene utilizzata con il comando \index{shell!\texttt{csh}}
    \texttt{csh}. In GNU/Linux non è disponibile essendo sostituita da
    \texttt{tcsh}.
  \item \textbf{La tcsh}. È una evoluzione della \textit{C shell}, alla quale
    aggiunge \textit{history} e editing di linea e varie funzionalità
    avanzate. Viene utilizzata con il comando \index{shell!\texttt{tcsh}}
    \texttt{tcsh}. Si trova su vari Unix proprietari, ma è poco diffusa su
    GNU/Linux, pur essendo disponibile.
  \end{itemize}
\end{itemize}

Dato che è il principale strumento di lavoro di un amministratore
professionista, la scelta della shell è spesso una questione strettamente
personale. Qui parleremo però solo di \texttt{bash}, che è la shell utilizzata
in praticamente tutte le distribuzioni di GNU/Linux, e probabilmente è anche
la più potente e flessibile fra quelle disponibili. L'unico motivo per volerne
usare un'altra infatti è solo perché siete maggiormente pratici con quella,
nel qual caso probabilmente non avete bisogno di leggere questo capitolo.

Il riferimento più immediato per il funzionamento della \texttt{bash} è la sua
pagina di manuale, accessibile al solito con \texttt{man bash}. Probabilmente
questa è una delle più lunghe fra tutte le pagine di manuale: quella associata
alla versione 4.2 consta di ben 5459 righe, ed in effetti più che una pagina è
un manuale.  Per questo in seguito faremo riferimento, quando necessario, alle
varie sezioni in cui essa è divisa. Per le funzionalità più avanzate esiste
anche un ottimo manuale libero \cite{AdvBash}, tradotto pure in italiano.


\subsection{Sessioni di lavoro e \textit{job control}}
\label{sec:struct_job_control}


\index{sessione~di~lavoro|(}
\index{terminale~di~controllo|(}

Come accennato in sez.~\ref{sec:shell_design}, l'uso dell'interfaccia a riga
di comando è strettamente legato all'uso di un terminale sul quale opera una
shell, il \textsl{terminale di controllo}, all'interno di quella che viene
solitamente chiamata una ``\textsl{sessione di lavoro}''. Questo ci aveva già
portato in sez.~\ref{sec:struct_proc_property} a tracciare una distinzione fra
i processi che avevamo classificato come interattivi, perché associati ad un
terminale di controllo, visibile nell'output di \texttt{ps} alla colonna
\texttt{TTY}, e quelli non interattivi, o meglio quelli che non lo sono
tramite l'interfaccia a riga di comando, che non hanno nessun terminale di
controllo.

Ai tempi in cui si aveva a disposizione un solo terminale (Unix è nato quando
ancora i terminali erano delle telescriventi, ed anche in seguito venivano
utilizzati terminali seriali come i VT100) se questo fosse stato utilizzabile
da un solo processo alla volta, non si sarebbero potute sfruttare le capacità
di multitasking del sistema. Per questo vennero introdotte delle funzionalità
che permettessero di lanciare ed usare contemporaneamente più programmi
attraverso un solo terminale, cosa che viene realizzata appunto attraverso il
sistema del cosiddetto \textsl{controllo di sessione}.  Oggi, con la
possibilità di avere più \textit{console} virtuali, e con l'interfaccia
grafica che non fa riferimento ad un terminale, questo problema non c'è più,
ma l'interfaccia è rimasta e mantiene comunque una sua utilità, ad esempio in
presenza di una connessione diretta via modem in cui si ha a disposizione un
solo terminale, e si devono eseguire compiti diversi.

\index{sessione~di~lavoro|)}

\itindbeg{standard~input}
\itindbeg{standard~output}
\itindbeg{standard~error}

Per spiegare le modalità in cui viene realizzata l'interazione tramite il
terminale, occorre anticipare una caratteristica fondamentale dell'interfaccia
a riga di comando. Tutte le volte che si lancia un programma che deve
interagire con la riga di comando, questo si aspetta di avere a disposizione e
già aperti tre file (torneremo su questo, e su come utilizzare queste
funzionalità, in sez.~\ref{sec:shell_IO_redirect}) che convenzionalmente sono
chiamati \textit{standard input}, \textit{standard output} e \textit{standard
  error}. Dato che questi sono i primi tre file aperti e lo sono in questa
sequenza, ad essi vengono sempre assegnati rispettivamente i \textit{file
  descriptor} 0, 1 e 2.\footnote{come accennato in
  sez.~\ref{sec:struct_filesystem_arch} il sistema mantiene anche una lista
  dei file aperti dai vari processi, ciascun processo a sua volta ha una lista
  dei file che ha aperto, il cui indice è appunto un numero chiamato
  \textit{file descriptor}, per maggiori dettagli riguardo a questa
  problematica si può consultare sez.~5.1.1 di \cite{GaPiL}.}

Convenzionalmente un programma legge i suoi dati in ingresso dal primo file
descriptor, scrive i dati in uscita sul secondo, e gli eventuali errori sul
terzo. Si tenga presente che è solo una convenzione, anche se seguita in
maniera universale, si può tranquillamente scrivere un programma che si
comporta in modo diverso, scrivendo e leggendo da un file descriptor
qualunque, ma ovviamente si avranno problemi di interazione con gli altri
programmi. 

Quando un processo è interattivo nel senso appena illustrato, tutti e tre
questi file corrispondono al terminale di controllo, e l'interfaccia dei
terminali (cioè quella dei dispositivi di questo tipo) fa sì che in lettura il
kernel faccia arrivare sullo \textit{standard input} quanto scritto sulla
tastiera e che quanto scritto sullo \textit{standard output} venga stampato
sullo schermo, o sulla finestra dentro l'interfaccia grafica, qualora si usi
un emulatore di terminale, o trasmesso via rete, se si usa un terminale
associato ad una connessione remota. Dato che, come accennato in
sez.~\ref{sec:struct_proc_architecture}, i file aperti vengono ereditati dai
processi figli e mantenuti nell'esecuzione di un nuovo
programma,\footnote{l'argomento è in realtà molto complesso e qui stiamo
  semplificando brutalmente, per una trattazione dettagliata si consultino
  sez.~3.1 e sez.~5.1 di \cite{GaPiL}.} basta che questi file siano aperti
all'inizio, e lo resteranno per tutti i processi lanciati in seguito.

Per capire meglio questa infrastruttura vediamo un esempio della sua
applicazione. Come accennato una delle modalità per utilizzare l'interfaccia a
riga di comando è quella di collegarsi ad una \textit{console} con la
tradizionale procedura di login su terminale; nei risultati del comando
\texttt{ps} mostrati a pag.~\pageref{sec:process_ps_out} si può notare come
sia presente il processo \index{comando!\texttt{getty}} \texttt{getty}
associato ad alcuni terminali virtuali (da \texttt{tty1} a
\texttt{tty6}). 

Questo è il programma che normalmente cura la procedura di login su una
\textit{console}, dando l'avvio alla conseguente sessione di lavoro, quasi
tutte le distribuzioni infatti attivano nella procedura di avvio (tratteremo
l'argomento in sez.~\ref{sec:struct_sysv_init}) sei \textit{console} virtuali
a cui si accede con la combinazione di tasti \texttt{Alt-FN}, dove
``\texttt{N}'' è il numero della rispettiva \textit{console}, cosa che
consente di avere diverse sessioni di lavoro usando un solo monitor ed una
sola tastiera.

In questo caso è \texttt{getty} che si cura dell'apertura iniziale dei tre
file di \textit{standard input}, \textit{standard output} e \textit{standard
  error} facendo riferimento al terminale che gli è stato indicato, nel caso
una delle \textit{console} virtuali, corrispondenti ai terminali da
\texttt{/dev/tty1} a \texttt{/dev/tty6}, che diventerà il terminale di
controllo di tutta la seguente sessione di lavoro. Poi il programma stampa un
messaggio di benvenuto e la linea ``\texttt{login: }'' e si pone in attesa che
un utente scriva sul terminale il suo ``\textit{username}'' (il cosiddetto
\textsl{nome utente} o \textsl{nome di login}), che come accennato è il nome
con cui un utente si identifica presso il sistema (torneremo sull'argomento in
sez.~\ref{sec:user_account}).

Una volta che questo sia stato scritto, \texttt{getty} esegue direttamente il
programma \index{comando!\texttt{login}} \texttt{login} che si cura di
chiedere la password ed effettuare l'autenticazione\footnote{in questo caso si
  tratta proprio dell'invocazione diretta del comando senza passare attraverso
  un nuovo processo, questo significa che il PID del processo resterà lo
  stesso.}. Se questa ha successo è \texttt{login} che si incarica di
impostare il valore del \textit{session ID} per il processo in corso, cambiare
gli identificativi ad esso associati (cioè l'\textit{user ID} ed il
\textit{group ID} visti in sez.~\ref{sec:struct_multiuser}) per farli
corrispondere a quelli dell'utente che si è collegato, ed infine lanciare
quella che si chiama una ``\textsl{shell di login}''.

In questo caso il programma invocato è sempre lo stesso, ma dato che come
vedremo più avanti una shell può essere utilizzata con modalità diverse
(all'interno di uno script non interattivo, o come \textit{sub-shell}
all'interno di una sessione) esistono delle opportune opzioni che consentono
di indicare la modalità di utilizzo: quella che indica una \textsl{shell di
  login} è una di queste, (torneremo sull'argomento in
sez.~\ref{sec:shell_operation_modes}). In tutta questa procedura i tre file di
\textit{standard input}, \textit{standard output} e \textit{standard error}
resteranno aperti ed associati al terminale di controllo da cui si è partiti,
che è quello su cui verrà utilizzata la shell.

\itindend{standard~input}
\itindend{standard~output}
\itindend{standard~error}

Una volta completata la procedura di collegamento avremo a disposizione una
shell con un certo valore del \textit{session ID}, e dato che anche questa è
una proprietà che viene conservata quando si creano processi figli e si
lanciano altri comandi, si avrà come conseguenza che anche tutti i processi
lanciati da detta shell saranno identificati dallo stesso \textit{session ID}.
Tutto ciò vale anche per tutte le altre modalità con cui si può iniziare una
sessione di lavoro su un terminale, che sia attraverso un emulatore ad
interfaccia grafica o un programma di connessione remota.

Come accennato in sez.~\ref{sec:struct_proc_property} le informazioni relative
alla sessione possono essere visualizzate con l'opzione \texttt{-j} di
\texttt{ps}, ad esempio lanciando il comando dal terminale in cui si stava
scrivendo questo testo abbiamo ottenuto il seguente risultato:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{ps -je f}
\end{Console} 
%$
\begin{Terminal}
  PID  PGID   SID TTY      STAT   TIME COMMAND
    1     0     0 ?        S      0:02 init [2]
...
 1820  1820  1820 tty1     Ss     0:00 /bin/login --     
 2112  2112  1820 tty1     S      0:00  \_ -bash
18911 18911  1820 tty1     S+     0:00      \_ top
...
 2882  2214  2214 ?        Sl     0:20 gnome-terminal
 2886  2214  2214 ?        S      0:00  \_ gnome-pty-helper
15894 15894 15894 pts/3    Ss     0:00  \_ bash
16065 16065 15894 pts/3    S      0:33  |   \_ emacs struttura.tex
16073 16073 15894 pts/3    Sl     0:29  |   \_ evince corso.pdf
18552 18552 15894 pts/3    R+     0:00  |   \_ ps -je f
17030 17030 17030 pts/0    Ss     0:00  \_ bash
20548 20548 17030 pts/0    S+     0:00      \_ watch ls -lR / | wc -l
20549 20548 17030 pts/0    S+     0:00          \_ watch ls -lR / | wc -l
20550 20548 17030 pts/0    S+     0:00              \_ sh -c ls -lR / | wc -l
20551 20548 17030 pts/0    R+     0:02                  \_ ls -lR /
20552 20548 17030 pts/0    S+     0:00                  \_ wc -l
...
\end{Terminal}

In questo caso la shell su cui si sta lavorando è stata lanciata all'interno
di una sessione associata al terminale virtuale \texttt{pts/3}, creata da
\texttt{gnome-terminal} all'interno dell'interfaccia grafica. Tutti i
programmi che si sono lanciati da questa shell (\texttt{evince},
\texttt{emacs} e lo stesso \texttt{ps}) hanno lo stesso valore nella colonna
\texttt{SID} dato che appartengono alla stessa sessione di lavoro. Lo stesso
dicasi per l'altra sessione di lavoro in una diversa finestra di
\texttt{gnome-terminal} dove viene eseguito \texttt{watch}, e per la sessione
di lavoro sulla \textit{console} \texttt{tty1} lanciata da \texttt{getty} che
sta eseguendo \texttt{top}.

Il risultato di \texttt{ps} mostra anche una seconda caratteristica delle
sessioni di lavoro, associata a quello che viene chiamato \textit{job
  control}: quando si lancia una linea di comando che comporta l'avvio di
altri processi, come quella con \texttt{watch}, tutti questi processi (nel
caso \texttt{ls}, \texttt{wc} e la sub-shell che li esegue) vengono assegnati
allo stesso \textit{process group}, e pertanto hanno lo stesso valore del
relativo identificativo nella colonna \texttt{PGID}.

La modalità più comune di uso della shell è quella in cui si lancia un
comando, si aspetta che questo completi le operazioni, e poi se ne lancia un
altro, e così via.  Quello che succede in questo caso è che per ogni comando
la shell crea un nuovo processo e si ferma in attesa che questo completi le
sue operazioni. Alla conclusione del programma la shell riprende il possesso
del terminale e consente di lanciare un altro comando.\footnote{se si ricorda
  quanto detto in sez.~\ref{sec:struct_proc_property} riguardo alla gestione
  della conclusione dei processi figli, essendo la shell il processo padre dei
  comandi che mette in esecuzione, essa viene sempre notificata anche della
  loro conclusione.} In genere si lavora in questo modo perché tutte le volte
che si esegue un programma interattivo questo deve avere a disposizione il
terminale di controllo per ricevere i dati in ingresso ed inviare i dati in
uscita.

Ovviamente se fosse possibile lavorare solo in questo modo si perderebbe la
possibilità di eseguire contemporaneamente più comandi e di sfruttare le
capacità multitasking del sistema. Se però si osserva il precedente risultato
di \texttt{ps} si potrà notare come tutti i comandi citati (\texttt{evince} ed
\texttt{emacs}), pur facendo riferimento allo stesso terminale, vengono
eseguiti insieme: essi infatti sono stati lanciati come suol dirsi in
\textit{background}, in una modalità cioè in cui essi non sono agganciati al
terminale.

Questa è un'altra funzionalità della shell che consente, quando si termina una
linea di comando con il carattere ``\texttt{\&}'', di mandare in esecuzione i
processi sganciati dal terminale, così che questo resti a disposizione della
shell stessa per eseguire altri comandi.  Se, come accade per i citati
\texttt{evince} ed \texttt{emacs} con cui si interagisce attraverso
l'interfaccia grafica, il programma non ha bisogno di accedere al terminale
per funzionare, esso potrà continuare ad eseguire le sue operazioni restando
appunto ``\textsl{sullo sfondo}''.  

Altrimenti al primo tentativo di accesso il programma riceverà dal kernel un
opportuno segnale in modo da bloccarne l'esecuzione,\footnote{i segnali sono
  rispettivamente \texttt{SIGTTIN} se l'accesso è in lettura e
  \texttt{SIGTTOU} se l'accesso in scrittura e l'azione di default di entrambi
  è quella di sospendere l'esecuzione del processo.} anzi in realtà il segnale
verrà inviato a tutti i processi che fanno parte dello stesso \textit{process
  group}, perché, come illustrato nei risultati di \texttt{ps} per quanto
riguarda la sessione in cui viene eseguito \texttt{watch}, e come vedremo
meglio anche in sez.~\ref{sec:shell_IO_redirect}, si possono eseguire più
processi su una singola riga di comando e se il terminale non è disponibile
dovranno essere fermati tutti.

Vediamo allora un esempio di questo comportamento, se si lancia in
\textit{background} un editor testuale come \texttt{jed}, otterremo che
l'esecuzione del comando viene immediatamente fermata, dato che ovviamente un
editor necessita di interagire con il terminale per poter essere utilizzato e
la shell stamperà un avviso per avvisarci dell'avvenuto blocco del
programma;\footnote{il sistema prevede anche che un processo padre possa
  essere notificato se uno dei suoi figli viene fermato, per i dettagli si
  consulti sez.~3.1.5 di \cite{GaPiL}.}  avremo cioè qualcosa del tipo:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{jed prova &}
[3] 22913

[3]+  Stopped                 jed prova
\end{Console}
%$

Tutte le volte che, come nell'esempio, si manda un processo in
\textit{background}, la shell stampa sul terminale un valore numerico fra
parentesi quadre, detto \textit{job ID} (dato che in gergo si suole chiamare
\textit{job} un processo che lavora in \textit{background}) seguito dal PID
del processo. La shell infatti identifica i processi attivi all'interno di una
stessa sessione di lavoro assegnando loro un numero progressivo, il
\textit{job ID}, che poi può essere utilizzato come riferimento nei vari
comandi di gestione del \textit{job control}. L'esempio ci mostra anche come
la shell provveda a stampare una notifica sul terminale tutte le volte che un
processo viene bloccato, utilizzando di nuovo il \textit{job ID}.

Oltre a lanciare un processo in \textit{background} ci sono casi in cui può
esser necessario fermare temporaneamente un comando in esecuzione, per
eseguire un controllo o un qualche altro compito più urgente. Abbiamo visto in
sez.~\ref{sec:struct_signal} che è possibile fermare l'esecuzione di un
processo con l'invio dei segnali \texttt{SIGSTOP} o \texttt{SIGTSTP}, il
sistema del controllo di sessione semplifica questa operazione permettendo di
inviare \texttt{SIGTSTP} ai processi che sono attivi su un terminale, tramite
la combinazione di tasti \texttt{C-z}, cioè l'uso del tasto
``\textit{control}'' insieme alla lettera ``\texttt{z}'' (la notazione è
formalizzata in sez.~\ref{sec:emacs-e-xemacs}).

Di nuovo la shell si accorgerà che il processo è stato fermato stampando, come
nell'esempio precedente, un messaggio di notifica prima di rimetterci a
disposizione il terminale. Oltre a \texttt{SIGTSTP} quando un processo è
associato ad un terminale di controllo gli si possono mandare altri segnali
con delle opportune combinazioni di tasti: \texttt{C-c} invia un
\texttt{SIGINT} e \texttt{C-\bslash} invia un \texttt{SIGQUIT}. Un elenco
delle principali combinazioni di tasti supportate dall'interfaccia dei
terminali è riportata in tab.~\ref{tab:terminal_control_key}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Combinazione} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{C-z} & sospende l'esecuzione del comando corrente con
     \texttt{SIGTSTP}.\\ 
     \texttt{C-c} & interrompe l'esecuzione del comando corrente con
                    \texttt{SIGINT}.\\ 
     \texttt{C-\bslash} & interrompe l'esecuzione del comando corrente con
                    \texttt{SIGQUIT}.\\
     \texttt{C-d} & invia il carattere di \textit{end-of-file}, che chiude lo 
                    \textit{standard input}.\\
     \texttt{C-s} & blocca le operazioni di I/O sul terminale.\footnotemark\\
     \texttt{C-q} & riabilita le operazioni di I/O sul terminale.\\
    \hline
  \end{tabular}
  \caption{Le scorciatoie da tastiera dell'interfaccia dei terminali.} 
  \label{tab:terminal_control_key}
\end{table}

\footnotetext{vengono cioè bloccate le operazioni di lettura e scrittura sul
  terminale, con la conseguenza di bloccare anche l'accesso alla riga di
  comando da parte della shell, la cui esecuzione si ferma in attesa che
  questo venga riabilitato; quanto si scrive sul terminale viene comunque
  ricevuto e memorizzato ma non ha nessun effetto, la shell infatti non lo
  riceverà fintanto che non si riabilitano le operazioni di I/O.}

L'elenco dei processi in \textit{background} o bloccati sul terminale può
essere stampato con il comando \index{comando!built-in!\texttt{jobs}}
\texttt{jobs}, che mostra la lista e lo stato di ciascuno di essi. Si tenga
presente che questo, come i seguenti \texttt{bg}, \texttt{fg} e \texttt{wait},
è un comando interno della shell, e non corrisponde a nessun eseguibile su
disco, (vedremo la differenza in sez.~\ref{sec:shell_sintax}).  Di default il
comando stampa l'elenco ordinandolo per \textit{job ID}, ma gli si possono
fare stampare anche i PID con l'opzione \texttt{-l}.  L'elenco riporta il
\textit{job ID} in prima colonna, seguito dallo stato e dal comando eseguito,
nella forma:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{jobs}
[1]   Running                 emacs struttura.tex &
[2]-  Running                 evince corso.pdf &
[3]+  Stopped                 jed prova
\end{Console}
%$
dove il carattere ``\texttt{+}'' indica il cosiddetto \textit{job}
\textsl{corrente}, cioè il processo su cui si è operato per ultimo, mentre il
carattere ``\texttt{-}'' indica il \textit{job} precedente (per maggiori
dettagli consultare il manuale della \texttt{bash} alla sezione ``\texttt{JOB
  CONTROL}'').

Quando un programma è stato fermato con \texttt{C-z} la shell ci consente di
farlo ripartire in \textit{background} con il comando
\index{comando!built-in!\texttt{bg}} \texttt{bg}, ovviamente se questo dovesse
cercare di eseguire un accesso a terminale si bloccherebbe immediatamente, per
questo è inutile usare \texttt{bg} su un comando che si è fermato per questo
motivo: si fermerà di nuovo.  Un processo può essere riassociato al terminale,
cioè essere rimesso, come suol dirsi, in \textit{foreground}, con il comando
\index{comando!built-in!\texttt{fg}} \texttt{fg}, se il processo era stato
fermato in attesa di poter disporre del terminale in questo modo viene anche
fatto ripartire.

Se non si specifica nulla sia \texttt{bg} che \texttt{fg} che tutti gli altri
comandi del controllo di sessione agiscono sul \textit{job} \textsl{corrente}.
Qualora si voglia invece agire su uno specifico \textit{job} si può
specificare come parametro sia il testo della riga di comando, che il numero
di \textit{job ID} stampato da \texttt{jobs} e questo può essere indicato sia
direttamente che preceduto da un carattere ``\texttt{\%}''. Quest'ultima
sintassi può essere usata anche con il comando \texttt{kill}, se questo è
realizzato come comando interno della shell come avviene nel caso di
\texttt{bash}, per mandare i segnali ad un processo identificato per
\textit{job ID} piuttosto che per PID.

Se si vuole aspettare la fine di uno specifico comando che si è mandato in
\textit{background} si può usare il comando
\index{comando!built-in!\texttt{wait}} \texttt{wait}, passandogli di nuovo il
\textit{job ID} come argomento. Se non si specifica nulla il comando aspetta
la fine di tutti i processi in \textit{background}. Questo comando può essere
utile negli script di shell (vedi sez.~\ref{sec:shell_scripting}) quando si è
lanciato un comando in \textit{background} per poter eseguire nel frattempo
altre operazioni, compiute le quali si vuole aspettare che il comando iniziale
finisca.

Una volta che si voglia terminare una sessione ed uscire dalla shell si può
usare il comando \index{comando!built-in!\texttt{exit}} \texttt{exit} o la
combinazione di tasti \texttt{C-d} che, come riportato in
tab.~\ref{tab:terminal_control_key}, corrisponde ad inviare un carattere di
\textit{end-of-file} sul terminale, cosa che segnala alla shell che lo si
vuole chiudere e con questo terminare la sessione di lavoro.

Se si cerca di uscire dalla shell e chiudere la sessione ma ci sono
\textit{job} in \textit{background} o bloccati, la shell stamperà un avviso
senza uscire, così da poter provvedere a risolvere la situazione. Se però si
ripete immediatamente la richiesta di chiusura, questa verrà onorata e la
shell verrà terminata insieme ai processi pendenti. Il comando \texttt{exit}
prende anche un argomento opzionale che costituisce lo stato di uscita
(torneremo su questo in sez.~\ref{sec:shell_scripting}) e viene usato
principalmente per uscire all'interno degli script .

Infine ci si può chiedere cosa succede se si interrompe la connessione ad un
terminale, ad esempio se si interrompe una connessione remota, su cui sono in
esecuzione dei programmi (in \textit{background} o meno). In tal caso il
kernel provvede ad inviare il segnale \texttt{SIGHUP} a tutti i processi che
hanno quello come terminale di controllo, l'effetto di default di questo
segnale è causare la terminazione del processo, onde evitare continui ad
essere eseguito senza poter riportare nessun risultato.  Il nome del segnale
deriva dall'inglese ``\textit{hungup}'' (\textsl{impiccato}) in quanto in casi
come questo un processo resterebbe \textsl{appeso} nel vuoto senza poter avere
nessuna interazione esterna.\footnote{abbiamo accennato in
  sez.~\ref{sec:struct_signal} come questo segnale venga utilizzato anche per
  dire ai demoni di sistema di rileggere i propri file di configurazione;
  questo non è in contrasto con quanto appena detto, in quanto detti programmi
  sono caratterizzati dal non avere un terminale di controllo, per cui
  \texttt{SIGHUP} può essere riutilizzato con un significato diverso.}  È per
questo motivo che se si esegue un programma da un emulatore di terminale
sull'interfaccia grafica (ad esempio si lancia un editor) e poi si chiude il
terminale, viene chiuso anche il programma che si è lanciato.

\index{terminale~di~controllo|)}

Esistono comunque alcune situazioni in cui questo comportamento non è
desiderato, ad esempio se si vuole lanciare su una macchina remota un
programma che non necessita di utilizzare il terminale, come un programma di
elaborazione dati. Per evitare la terminazione in caso di disconnessione o di
uscita dalla shell si può anteporre \index{comando!\texttt{nohup}}
\texttt{nohup} alla riga di comando che si vuole eseguire, che a questo punto
verrà eseguita senza terminale di controllo e non terminerà una volta che ci
si scolleghi da esso.

In questo caso, dato che non si vuole neanche che il programma si fermi in
caso di accesso al terminale, qualora esso generi dell'output questo verrà
scritto in coda al file \texttt{nohup.out}, nella directory in cui si è
lanciato il programma. Se questo file non fosse accessibile verrebbe usato al
suo posto un file \texttt{nohup.out} nella \textit{home} dell'utente, ed in
caso di inaccessibilità anche di quest'ultimo si avrebbe un errore.

La \texttt{bash} consente anche, qualora si sia già lanciato un programma, di
utilizzare il comando \index{comando!built-in!\texttt{disown}} \texttt{disown}
per disassociare un processo in \textit{background} dalla tabella dei
\textit{job}, ed evitare così che gli venga inviato il segnale di
\texttt{SIGHUP} all'uscita della shell, si può comunque mantenere il programma
nella lista dei \textit{job} e disabilitare solo l'invio di \texttt{SIGHUP}
usando l'opzione \texttt{-h}.  Se non si specifica nulla il comando si applica
al \textit{job corrente}, altrimenti può specificare uno o più \textit{job
  ID}, o l'opzione \texttt{-r} per indicare i programmi attualmente in
esecuzione o l'opzione \texttt{-a} per indicare tutti i programmi della
sessione di lavoro.

Entrambe queste soluzioni però rendono impossibile riprendere in mano una
sessione avviata e non funzionano se il comando per un qualche motivo richiede
dei dati in ingresso. Per ovviare a questo inconveniente e rendere possibile
interrompere e riprendere una sessione di lavoro in qualunque momento, si può
invece usare il comando \index{comando!\texttt{screen}} \texttt{screen}, che
consente di creare un numero arbitrario di sessioni indipendenti gestite
all'interno del comando stesso. In questo modo è possibile distaccarsi da una
di queste sessioni lasciandovi in esecuzione i propri programmi, e
ricollegarsi in un secondo momento (si può ad esempio passare da un
collegamento in locale ad uno remoto via SSH).

Se lanciato senza argomenti \texttt{screen} apre una nuova sessione, chiedendo
di confermarne la creazione con un invio, e vi si \textsl{aggancia}. Il
programma simula un terminale virtuale il cui contenuto viene riportato sul
terminale da cui lo si è invocato. Si può anche specificare come argomento una
riga di comando che verrà eseguita all'interno della sessione
stessa. All'interno della sessione il programma intercetta la combinazione di
tasti \texttt{ctrl-a}, per eseguire le proprie operazioni. Ad esempio con
\texttt{ctrl-a~d} ci si \textsl{distacca} dalla sessione di \texttt{screen}
tornando nella sessione di partenza, con \texttt{ctrl-a~h} si salva sul file
\texttt{hardcopy.\textsl{n}} una copia della schermata, con \texttt{ctrl-a~a}
si passa un \texttt{ctrl-a} al terminale sottostante. Con opportune
combinazioni (per le quali si rimanda alle pagine di manuale) è possibile
anche creare delle ulteriori \textsl{finestre} interne, associate ad
altrettante sessioni e terminali, in cui eseguire altri programmi in maniera
totalmente indipendente gli uni dagli altri e passare dall'una all'altra.

Quanto eseguito all'interno di una sessione di \texttt{screen} userà il
terminale virtuale ad essa associato, sia che questo sia associato ad un
terminale da cui si osserva la sessione, sia che sia \textsl{distaccato}. Si
tenga presente che tratta comunque di un terminale elementare (un VT100), con
una limitata memoria per la visualizzazione dello \textit{standard output},
per cui in genere restano disponibili solo le ultime righe dell'output del
comando. Una volta distaccatisi si potrà riagganciarsi ad una sessione avviata
in precedenza invocando il comando da un qualunque altro terminale con
l'opzione \texttt{-r}.  

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-d \textsl{[sess]}} & forza la disconnessione di una sessione agganciata ad
                                  un'altra istanza del comando, si può abbinare a \texttt{-r}
                                  per forzare la connessione e a \texttt{-m} per creare una
                                  sessione disconnessa.\\ 
    \texttt{-h} & imposta il numero di righe di terminale da ricordare nello
                  scorrimento all'indietro del terminale virtuale interno.\\ 
    \texttt{-r \textsl{[sess]}} & si aggancia ad una sessione (che deve essere
                                  distaccata) se ve ne sono disponibili più di
                                  una si deve indicare quale.\\ 
    \texttt{-R} & si connette alla sessione distaccata più recente, creandone
                  una nuova se nessuna è disponibile.\\ 
    \texttt{-S \textit{sess}} & imposta un nome specifico per la sessione, sovrascrive il
                                default di \texttt{\textsl{pid}.\textsl{tty}.\texttt{host}}.\\ 
    \texttt{-x} & forza la connessione anche se la sessione è gestita da
                  un'altra istanza del comando, condividendo il terminale virtuale.\\ 
    \texttt{-X} & invia il comando passato come argomento ad una sessione (se
                  ve ne sono disponibili più di una si deve specificare quale
                  con \texttt{-S}).\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{screen}.} 
  \label{tab:screen_options}
\end{table}

Se è disponibile una sola sessione di lavoro si verrà immediatamente
riagganciati alla stessa, mentre se ve ne sono più di una il comando fallirà
stampando la lista delle stesse, nella forma
\texttt{\textsl{pid}.\textsl{tty}.\texttt{host}} che consente di identificarle
univocamente, e si potrà selezionare quella voluta passando la relativa
stringa identificativa come argomento per \texttt{-r}. Ci si può collegare
solo alle sessioni create con il proprio utente, solo l'amministratore è in
grado di agganciarsi a sessioni di altri utenti, usando una stringa
identificativa nella forma
\texttt{\textsl{user}/\textsl{pid}.\textsl{tty}.\texttt{host}}. 

Si tenga presente comunque che di default \texttt{screen} non consente di
agganciarsi ad una sessione ancora agganciata ad un'altra istanza del
programma; in questo caso se ne può forzare la disconnessione specificando
l'ulteriore opzione \texttt{-d} che può essere usata anche da sola per forzare
il distacco. Ci si può inoltre collegare anche senza forzare la disconnessione
con l'opzione \texttt{-x}, in tal caso le operazioni saranno effettuabili da
una qualunque delle istanze collegate, ottenendo una sorta di condivisione
dello schermo. Le altre principali opzioni di \texttt{screen} sono riportate
in tab.~\ref{tab:screen_options}, per la documentazione ed i dettagli si
rimanda al solito alla pagina di manuale.



\subsection{Sintassi e funzionalità di base della riga di comando}
\label{sec:shell_sintax}

Finora si è parlato di riga di comando e del fatto che la shell consente
all'utente di lanciare i vari programmi che vuole utilizzare, sorvolando però
sui dettagli delle modalità in cui questo viene fatto. In realtà la shell è un
programma molto complesso, e quello di interprete della riga di comando è
soltanto uno dei modi in cui può essere usata (torneremo su questo in
sez.~\ref{sec:shell_scripting}), inoltre anche in questo caso (quando cioè si
ha a che fare con quella che si suole chiamare una \textsl{shell interattiva})
ci si è limitati a mostrare esempi elementari.

Per comprendere le reali capacità della shell e trattare la sintassi della
riga di comando occorre prima approfondire le modalità con cui la shell legge
una riga dalla tastiera, riconosce qual è il programma che volete mettere in
esecuzione, ricostruisce i vari argomenti da passare al programma stesso, e
poi lo esegue.  L'invocazione generica di un qualunque comando è nella
forma:\footnote{in realtà anche in questo caso ci stiamo limitando ad una
  invocazione elementare, vedremo in seguito come l'uso di una serie di
  caratteri di controllo consente di modificare il comportamento della shell.}
\begin{Example}
comando -o -v valore --altra-opzione argomento1 --riopzione=valore arg2
\end{Example}
da scrivere sulla stessa riga e terminare con la pressione del tasto di
invio. 

La pressione del tasto di invio su un terminale infatti serve a
``\textsl{scaricare}'' la linea appena scritta in modo che questa possa essere
letta in ingresso dal programma che usa il terminale (nel nostro caso la
shell). Se si vuole scrivere un comando su più righe andando a capo occorrerà
proteggere la pressione del tasto di invio; questo si fa utilizzando il
carattere ``\texttt{\bslash}'' come ultimo carattere della riga, vedremo più
avanti che ``\texttt{\bslash}'' può essere usato nello stesso modo con gli
altri caratteri.

La sintassi elementare della shell prevede che si scriva all'inizio della riga
(eventuali spazi antistanti verranno comunque ignorati) il nome del comando da
eseguire, seguito da eventuali opzioni ed argomenti. Si tenga presente che la
shell, per identificare il comando e separarlo da opzioni e argomenti, e
separare questi ultimi fra di loro, usa caratteri vuoti come lo spazio o il
tabulatore. La presenza cioè di uno o più spazi o tabulatori dice che si sta
passando dal nome del comando ad un argomento o opzione, o da un
argomento/opzione al successivo. Lo stesso dicasi qualora si vada a capo su
una nuova riga con l'uso del ``\texttt{\bslash}''.

Per questo motivo il nome di un comando non contiene spazi, inoltre la
stragrande maggioranza dei comandi usa nomi scritti esclusivamente in lettere
minuscole, si ricordi infatti che un sistema unix-like è case-sensitive, fa
differenza cioè fra maiuscole e minuscole. I soli caratteri non alfabetici
utilizzati nei nomi dei comandi, in genere assai poco, sono il ``\texttt{-}''
e il ``\texttt{\_}'' ed eventualmente i numeri.  Gran parte degli altri
caratteri infatti, come vedremo fra breve, vengono interpretati dalla shell
assumendo significati speciali, e pertanto di nuovo non possono essere
inseriti nel nome del comando, almeno non senza prendere adeguate precauzioni,
analoghe a quelle che vedremo più avanti per gli argomenti, il che poi fa sì
che si finisca per usare nomi con semplici caratteri alfanumerici.

La differenza fra opzioni e argomenti è che le prime attivano funzionalità o
modalità di operazione specifiche del comando, mentre i secondi indicano gli
oggetti, solitamente dei file, su cui questo opera.  In realtà il meccanismo è
un po' più complesso, e può essere compreso nei dettagli solo con un po' di
nozioni di programmazione.\footnote{per i curiosi questo argomento è trattato
  in dettaglio nella sezione 2.3 di \cite{GaPiL}.} Quello che in effetti fa la
shell è identificare il programma da usare sulla base del nome del comando,
per poi spezzare l'intera riga in una lista di stringhe che verranno passate
al suddetto programma come argomenti iniziali.

Questa scansione viene eseguita su tutta la riga, utilizzando gli spazi vuoti
come separatori e senza distinguere fra nome del comando, opzioni e argomenti;
tutto il contenuto sarà suddiviso in una lista di stringhe, che poi il
programma dovrà analizzare al suo interno. Si tenga presente che opzioni ed
argomenti possono essere separati da un numero arbitrario di caratteri di
spaziatura, che saranno scartati. Vedremo più avanti come questo finisca con
l'avere diverse conseguenze non del tutto intuitive.

Per gestire gli argomenti e le opzioni passate dalla linea di comando la gran
parte dei programmi utilizzano una serie di funzioni fornite dalla libreria
fondamentale del sistema, la \textit{GNU C library} che abbiamo già incontrato
in fig.~\ref{fig:kernel}.\footnote{la funzionalità si chiama \textit{getopt},
  e permette l'uso di una sintassi standard per le opzioni, la scansione
  automatica delle stesse indipendentemente dall'ordine in cui le si
  specificano, la possibilità di identificare opzioni con parametri o senza,
  la capacità di passare al programma, una volta terminata la scansione della
  lista di stringhe ottenuta dalla shell, solo quelle contenenti gli argomenti
  restanti; per una trattazione più dettagliata si può fare riferimento alla
  sez.~2.3.2 di \cite{GaPiL}.} Per i programmi che usano queste funzionalità
questo comporta la presenza di un formato della riga di comando abbastanza
uniforme, mostrato appunto nell'esempio precedente, con la possibilità di
distinguere fra opzioni e argomenti, e di specificare questi in un ordine
qualunque. Si tenga presente che questo non è sempre vero, dato che non tutti
i programmi fanno ricorso a queste funzionalità. Per questo motivo troveremo
in seguito diverse eccezioni, ad esempio in cui l'ordine conta, o in cui le
opzioni vanno specificate prima degli argomenti.

Nel comportamento comune le opzioni sono sempre costituite da un carattere
``\texttt{-}'' seguito da una lettera ed in rari casi anche da numeri o
caratteri non alfabetici, a cui può seguire (separato o meno da uno spazio) un
eventuale valore passato come parametro, ma non tutte le opzioni prevedono
parametri, nel qual caso va specificata solo la lettera dell'opzione. Se si
specificano più opzioni è normalmente supportata anche la possibilità di
indicarle con più lettere scritte di fila dopo un ``\texttt{-}'' iniziale.

Una forma alternativa per le opzioni, in uso principalmente con i programmi
del progetto GNU che utilizzano le funzionalità della citata \textit{GNU C
  library} e anch'essa mostrata nell'esempio precedente, è quella in cui
l'opzione è scritta in forma \textsl{estesa}, e allora viene introdotta da un
``\texttt{-{}-}''. In questo caso, qualora essa necessiti di un parametro, il
relativo valore deve essere assegnato con l'uso di un ``\texttt{=}'', ma anche
questa è una convenzione, non è detto sia sempre supportata, ed in alcuni casi
si può scrivere direttamente il parametro senza l'assegnazione.  Torneremo su
questo, e su alcuni aspetti che riguardano gli effetti non immediatamente
evidenti dell'uso del carattere ``\texttt{-}'' nella sintassi della riga di
comando, in sez.~\ref{sec:cmd_general}.

Per capire meglio questo comportamento facciamo un esempio; si consideri di
aver scritto su un terminale una riga di comando contenente qualcosa del tipo:
\begin{Example}
rm -f pippo pluto paperino
\end{Example} 
la shell capirà che si intende invocare il comando \texttt{rm} e, individuato
su disco il file che contiene il relativo programma, lo lancerà passandogli
come argomenti le cinque stringhe presenti nella riga precedente. La prima
stringa, \texttt{rm}, contiene il nome del programma e di norma viene
ignorata, le restanti invece verranno analizzate dal programma; così
\texttt{-f} verrà identificata come opzione mentre, non necessitando questa di
nessun parametro, \texttt{pippo}, \texttt{pluto} e \texttt{paperino} verranno
considerati come argomenti, che nel caso indicano i file da cancellare.

In realtà alcuni programmi usano anche il nome stesso con cui vengono invocati
per modificare il loro comportamento, un esempio classico di questo
comportamento è \texttt{gzip}, un compressore di file su cui torneremo in
sez.~\ref{sec:cmd_file_filter}, che può essere invocato anche come
\texttt{gunzip} (in genere entrambi i comandi sono presenti come \textit{hard
  link} allo stesso file eseguibile) nel qual caso decomprimerà invece di
comprimere.

Si tenga conto poi che benché la filosofia di Unix sia quella di utilizzare un
apposito comando per effettuare ciascun compito specifico, e che il caso più
comune sia quello in cui la shell interpreta la riga di comando per lanciare
il programma che le avete chiesto, esistono alcune funzionalità che essa
fornisce direttamente tramite quelli che vengono detti \textsl{comandi
  interni} (o \textit{built-in}).  Se questo è il caso la shell si accorgerà
che non è necessario eseguire nessun programma esterno, ed opererà
direttamente sulla base di quanto dite sulla linea di comando. Di norma i
comandi interni sono quelli che servono a eseguire impostazioni relative al
funzionamento stesso della shell, o a impostare proprietà generali che essa
deve trasmettere ai programmi che lancia.

Un esempio classico di comando interno è \texttt{cd} che viene usato per
modificare la directory di lavoro corrente della shell. Un tale comando non
può essere eseguito con un programma esterno, dato che nella sua esecuzione
come processo separato quest'ultimo potrebbe solo cambiare la sua directory di
lavoro, ma non quella della shell che lo ha lanciato. Questo perché, come
accennato in sez.~\ref{sec:struct_filesystem_arch}, la directory di lavoro è
una delle caratteristiche che ciascun processo si porta dietro e quella
iniziale è \textsl{ereditata} dal processo padre; per questo se la si cambia
nella shell tutti i comandi successivi la vedranno, ma non viceversa.  Altri
esempi di comandi interni sono \texttt{umask} (visto in
sez.~\ref{sec:struct_file_perm_comm}), ed i comandi del controllo di sessione
di sez.~\ref{sec:struct_job_control}; ne incontreremo degli altri più avanti.

Si ricordi infine che quanto detto attiene all'uso più elementare della
sintassi usata dalla shell, quello in cui si esegue un comando scrivendone per
esteso il nome con le relative opzioni ed argomenti. Vedremo più avanti come
sulla linea di comando si possano effettuare operazioni anche molto complesse
attraverso l'uso di opportuni caratteri di controllo.

L'esempio precedente con \texttt{rm} ci mostra come la shell, oltre a quello
generico di lanciare programmi, già esegua di per sé anche molti altri
compiti. Il primo che prenderemo in esame è quello della visualizzazione del
\itindex{prompt} \textit{prompt}, cioè di quella scritta che compare sulla
sinistra della linea di comando, a fianco della quale, se non si è scritto
nulla, lampeggia il cursore, e che serve ad avvisarvi che la shell è in attesa
di ricevere dei comandi da eseguire.

Nel caso della \texttt{bash} il \textit{prompt} è completamente
personalizzabile, e può contenere diverse informazioni. Quello che viene
stampato come \textit{prompt} è stabilito dalla variabile di shell
\index{variabili!di~shell!\texttt{PS1}} \texttt{PS1},\footnote{in realtà in
  tutto le variabili che controllano l'aspetto del prompt sono 4, ed oltre
  \texttt{PS1} ci sono anche \texttt{PS2}, \texttt{PS3} e \texttt{PS4} che
  vengono utilizzate in altri casi (ad esempio
  \index{variabili!di~shell!\texttt{PS2}} \texttt{PS2} viene usata come segno
  di continuazione di un comando quando si va a capo con l'uso di
  ``\texttt{\bslash}'' a fine riga); la descrizione dettagliata del loro
  impiego si trova nella pagina di manuale, nella sezione ``\texttt{Shell
    Variables}''.}  (tratteremo delle variabili di shell a breve) nel cui
contenuto, oltre ai normali caratteri, che saranno stampati inalterati, si
possono inserire una serie di caratteri di controllo (i principali dei quali
sono riportati in tab.~\ref{tab:shell_prompt_command}) che verranno
automaticamente \textsl{espansi} in un determinato valore (come data, utente,
stazione, ecc.).  L'elenco completo è disponibile nella pagina di manuale,
alla sezione ``\texttt{PROMPTING}''.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \verb|\d| & la data in formato tipo: \texttt{Tue May 26}.\\ 
    \verb|\h| & il nome della stazione.\\ 
    \verb|\u| & lo \textit{username} dell'utente.\\ 
    \verb|\w| & il percorso completo della directory di lavoro.\\ 
    \verb|\W| & il nome della directory di lavoro.\\ 
    \verb|\$| & un ``\texttt{\#}'' per l'amministratore, un ``\texttt{\$}''
                per gli altri.\\ 
    \verb|\!| & la posizione nella history del comando.\\ 
    \verb|\t| & il tempo corrente in formato HH:MM:SS (24h).\\ 
    \verb|\T| & il tempo corrente in formato HH:MM:SS (12h).\\ 
    \hline
  \end{tabular}
  \caption{Principali caratteri di controllo usati nella visualizzazione del
    prompt della shell.}
  \label{tab:shell_prompt_command}
\end{table}

Due esempi possibili per il prompt sono quello usato da Debian, che prevede
per \texttt{PS1} un valore pari a ``\verb|\u@\h:\w\$|'', e che produce un
prompt del tipo:
\begin{Example}
piccardi@anarres:~/truedoc/corso$
\end{Example}
%$
o quello di RedHat, che usa un valore di ``\verb|[\u@\h \W]\$|'', e produce un
prompt del tipo:
\begin{Example}
[root@gont piccardi]#
\end{Example}

La scelta del prompt dipende dai gusti e dall'uso: se ci si trova a lavorare
contemporaneamente con diversi utenti, su computer diversi, allora sarà utile
sapere con quale utente e su quale macchina si sta operando in un certo
terminale; altrimenti si può farne a meno e risparmiare spazio sulla linea di
comando con un valore di \texttt{PS1} come ``\verb|\$|''.

\index{variabili!di~shell|(}

Al di là dell'estetica del prompt il compito principale della shell è quello
di mettere a disposizione dell'utente un'interfaccia che gli consenta di
utilizzare al meglio il sistema; per questo essa fornisce una serie di
funzionalità che permettono di rendere più efficace l'uso dei comandi. Una
delle funzionalità fondamentali è quella delle \textsl{variabili di shell}; la
shell permette cioè di definire e modificare delle variabili a cui si può fare
riferimento in un secondo tempo. Per farlo la sintassi elementare della riga
di comando vista in precedenza cambia e si deve utilizzare una riga contenente
un'assegnazione nella forma:
\begin{Example}
VARIABILE=valore
\end{Example}

Se la variabile non esiste viene creata e assegnata, altrimenti viene
reimpostata al valore specificato. Si noti che non ci sono spazi a separare il
nome della variabile, l'operatore ``\texttt{=}'' ed il valore. In presenza di
spazi infatti la shell interpreterebbe il tutto come il nome di un comando, e
probabilmente riporterebbe un errore non trovando un programma
corrispondente. Si tenga presente comunque che la shell supporta anche la
possibilità di eseguire un comando una volta effettuata l'assegnazione di una
variabile, nel qual caso questo dovrà essere specificato, separato da uno
spazio, nel seguito della riga di comando.

Per convenzione le variabili di shell hanno nomi scritti con lettere
maiuscole, ma questa è appunto solo una convenzione, dovuta al fatto che così
è più difficile confonderle con i comandi; in realtà è possibile usare
qualunque tipo di lettera e, eccezion fatta per il primo carattere, anche
qualunque numero ed il carattere di sottolineatura ``\texttt{\_}''.

\itindbeg{variable~expansion}

Una volta definita una variabile di shell è possibile richiamarne il valore
sulla riga di comando anteponendo al nome della variabile il carattere
``\texttt{\$}''; così se ad esempio si è inserito nella variabile
\texttt{MAIL} il nome del file in cui si trova la propria posta elettronica,
si potrà verificarne dimensioni e permessi con un comando del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{ls -l $MAIL}
-rw-rw----    1 piccardi mail         4136 Aug 25 17:30 /var/mail/piccardi
\end{Console}

Questo perché la shell, quando incontra il carattere ``\texttt{\$}'' seguito
dal nome di una variabile, esegue quella che viene comunemente chiamata una
``\textit{variable expansion}'',\footnote{la pagina di manuale della
  \texttt{bash} invece fa riferimento a questa funzionalità come alla
  ``\texttt{Parameter Expansion}''.}  sostituisce cioè il riferimento alla
variabile (nel caso \texttt{\$MAIL}) con il valore della stessa (nel caso
\texttt{/var/mail/piccardi}), passando il risultato, come argomento o come
opzione a seconda di dove lo si è scritto, al comando che viene eseguito.

In realtà la \textit{variable expansion} è un procedimento molto più complesso
rispetto alla descrizione grossolanamente semplificata che si è appena fatta,
e senza comprenderne i dettagli si rischia di trovarsi di fronte a dei
risultati inaspettati. Tutte le volte che nella scansione della riga di
comando la shell incontra il carattere ``\texttt{\$}'' seguito da una lettera,
interpreta il tutto come l'inizio del riferimento ad una variabile, ed esegue
la sostituzione con il relativo valore.

Tutto questo può avere alcuni effetti non del tutto intuitivi: il primo è che
la sostituzione avviene comunque, indipendentemente dal fatto che sia stata
definita o meno una variabile che corrisponde a quel nome, anche se si può
forzare la stampa di un errore in questo tipo di situazione, modificando con
\texttt{set -u} il comportamento di default della shell (vedi le opzioni di
tab.~\ref{tab:shell_set_options}).

Questo significa che normalmente anche se una variabile non esiste la sua
\textit{variable expansion} avviene lo stesso, solo che non essendoci un
valore, al posto del riferimento non viene messo nulla, il che comporta che se
si sbaglia a scrivere il nome di una variabile non si avrà nessun errore
specifico, se non quelli dovuti al fatto che sulla riga di comando non compare
più un eventuale parametro o argomento che si era espresso tramite di essa. Si
ricordi infatti che prima la shell effettua la \textit{variable expansion} e
poi analizza la linea di comando che ne deriva per creare la lista di
argomenti ed opzioni da passare al programma. Questo in certi casi può portare
a risultati inaspettati perché l'eventuale errore deriva dalla mancanza di un
argomento e non dal fatto che questo sia nullo. 

Un secondo problema della \textit{variable expansion} è che se è semplice
determinare l'inizio del nome di una variabile, che corrisponde al carattere
che segue il ``\texttt{\$}'', non è altrettanto immediato identificarne la
fine. Questa nella sintassi esposta viene determinata dal primo carattere non
valido per il nome di una variabile. Per cui se ad esempio si definisce la
variabile \texttt{BASE=prova}, il riferimento a \texttt{\$BASE\_01} non darà
come risultato, come qualcuno avrebbe potuto aspettarsi, il valore
\texttt{prova\_01}, ma un valore nullo, perché la variabile \texttt{BASE\_01}
non esiste.

Per risolvere questo tipo di problemi la shell supporta una diversa sintassi
per eseguire la \textit{variable expansion}, che prevede l'indicazione
esplicita del nome della variabile fra parentesi graffe dopo il
``\texttt{\$}'', cioè, per riprendere l'esempio precedente, con qualcosa del
tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{ls -l $\{MAIL\}}
-rw-rw----    1 piccardi mail         4136 Aug 25 17:30 /var/mail/piccardi
\end{Console} 

Questa sintassi, oltre a definire in maniera chiara i caratteri che fanno
parte del nome della variabile (nel precedente esempio \texttt{\$\{BASE\}\_01}
è ben definito, e da come risultato \texttt{prova\_01}) consente anche di far
eseguire alla shell una serie di operazioni avanzate, come usare un
riferimento indiretto (cioè usare una variabile per contenere il nome di
quella da referenziare) impostare un valore di default, eseguire espansioni
condizionali, ed altre per la cui descrizione dettagliata si rimanda alla
sezione ``\texttt{Parameter Expansion}'' della pagina di manuale.

\itindend{variable~expansion}

Per poter vedere l'elenco delle variabili di shell che sono state definite
(vedremo in sez.~\ref{sec:shell_scripting} come effettuarne l'impostazione al
login o quando si esegue la shell su un terminale) si può usare il comando
interno \texttt{set}, che ne stampa a video la lista ed i relativi valori
nello stesso formato in cui si eseguono le assegnazioni. Il comando
\texttt{set} però, oltre alle variabili, stampa anche tutte le funzioni (vedi
sez.~\ref{sec:shell_scripting}) definite nella shell, per cui la lista
ottenuta può essere anche molto lunga e le variabili, che sono all'inizio, si
possono perdere di vista.\footnote{in realtà si può limitare la stampa alle
  sole variabili se lo si usa con la shell in modalità Posix, questo però
  cambia tutto il comportamento della shell, per una invocazione singola si
  può usare la sintassi \texttt{(set -o posix; set)} che esegue il comando in
  un sottoprocesso.}

Si tenga presente che \texttt{set} effettua la stampa delle variabili di shell
soltanto se invocato senza argomenti (il comando dedicato alla gestione delle
variabili in realtà è \texttt{declare}, che tratteremo a breve) mentre in
generale il comando viene invocato con le opportune opzioni per impostare
alcuni comportamenti di default della shell, torneremo su questo in
sez.~\ref{sec:shell_operation_modes}.

Qualora si voglia cancellare una variabile definita in precedenza si può usare
invece il comando interno \index{comando!built-in!\texttt{unset}}
\texttt{unset}, seguito dal nome della variabile, il comando è anche in grado,
quando usato con l'opzione \texttt{-f}, di cancellare una funzione di shell.
La modifica di una variabile di shell si effettua semplicemente assegnando
alla variabile un nuovo valore. Si tenga presente che benché sia possibile
cancellare il contenuto di una variabile assegnandole una stringa vuota,
questo non è equivalente a cancellarla con \texttt{unset}, dato che essa
resterebbe definita, anche se con valore nullo.

Si noti che mentre la shell fornisce la sintassi e gli opportuni comandi
interni per assegnare e cancellare la singola variabile, altrettanto non
accade per la visualizzazione del contenuto. Ciò avviene perché questo può
essere fatto attraverso l'uso di uno dei comandi specialistici della
\textit{Unix toolbox}.  In particolare il comando da usare è
\index{comando!\texttt{echo}} \texttt{echo},\footnote{si tenga presente che
  nel caso della \texttt{bash} il comando è disponibile anche come comando
  interno, per cui di default viene eseguita la versione interna fornita dalla
  shell.} il cui solo compito è stampare in uscita la stringa (o le stringhe)
che gli vengono passate come argomento: siccome la shell esegue
automaticamente l'espansione delle variabili prima di passare gli argomenti ad
un comando, si potrà usare \texttt{echo} per leggere il contenuto di una
variabile con una riga del tipo:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{echo $USER}
piccardi
\end{Console} 
dove la variabile \index{variabili!di~ambiente!\texttt{USER}} \texttt{USER}
viene prima \textsl{espansa} dalla shell nella stringa \texttt{piccardi}, dopo
di che quest'ultima viene passata come argomento ad \texttt{echo}, che, come
avrebbe fatto per una qualunque altra stringa che potreste aver scritto
direttamente sulla linea di comando, la stamperà a video.

Il comando \texttt{echo} è uno dei più elementari e prende due sole opzioni.
La prima è \texttt{-n}, che evita la stampa del carattere di a capo alla fine
della stringa passata come argomento.  Questa opzione è utile quando si vuole
costruire una riga di testo con più invocazioni del comando, e la si usa in
genere all'interno di uno \textit{script} (tratteremo gli script in
sez.~\ref{sec:shell_scripting}), dato che sul terminale si avrebbe
l'interferenza da parte del prompt.

La seconda opzione è \texttt{-e} che attiva l'interpretazione di espressioni
speciali, introdotte dal carattere ``\texttt{\bslash}'' (come \texttt{\bslash
  n}), che consentono di ottenere la stampa di una serie di caratteri di
controllo (nel caso un ritorno a capo).  L'elenco completo di queste
espressioni, insieme a tutti gli altri dettagli relativi al comando, si trova
nella relativa pagina di manuale, accessibile con \texttt{man echo}.

La \texttt{bash} definisce automaticamente alcune variabili e ne utilizza
delle altre qualora siano definite, ed in alcuni casi, se queste non sono
state definite, le utilizza impostandole automaticamente ad un valore di
default. In questo modo da una parte diventa possibile accedere ad una serie
di informazioni che possono essere riutilizzate sulla riga di comando,
dall'altra si può modificare il comportamento della shell scrivendo degli
opportuni valori nelle opportune variabili.  

Un elenco delle principali variabili predefinite riconosciute dalla shell è
riportato in tab.~\ref{tab:shell_predefined_variables}, mentre per l'elenco
completo e la descrizione di tutti i loro effetti si può consultare la sezione
``\texttt{Shell Variables}'' della pagina di manuale.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Variabile} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{BASH\_ENV} & se impostata viene usata nell'esecuzione degli
                          script (vedi sez.~\ref{sec:shell_scripting}) come
                          l'indicazione del file da cui leggere eventuali
                          impostazioni di inizializzazione.\\ 
     \texttt{GLOBIGNORE}& una lista, separata da ``\texttt{:}'', di nomi di
                          file da ignorare nel \textit{filename globbing}.\\
     \texttt{HISTFILE}  & il file in cui viene memorizzata la storia dei
                          comandi.\\ 
     \texttt{HISTFILESIZE}& il massimo numero di linee da mantenere nel file
                          della storia dei comandi.\\
     \texttt{HISTSIZE}  & il numero di comandi da mantenere nella storia dei
                          comandi. \\
     \texttt{HOME}      & la home directory dell'utente, viene usata anche dal
                          comando interno \texttt{cd}.\\
     \texttt{HOSTNAME}  & il nome della macchina.\\
     \texttt{IFS}       & elenco dei caratteri che separano in campi diversi
                          il risultato di una \textsl{espansione} di
                          shell.\\ 
     \texttt{LANG}      & la \textsl{localizzazione} utilizzata dai
                          programmi (vedi sez.~\ref{sec:localization}).\\
     \texttt{OSTYPE}    & la descrizione del sistema operativo corrente.\\
     \texttt{PATH}      & la lista delle directory in cui si trovano i
                          comandi.\\ 
     \texttt{PS1}       & la stringa che indica il formato del
                          \textit{prompt}.\\  
     \texttt{PWD}       & la directory di lavoro corrente.\\
     \texttt{SHLVL}     & livello della \textit{subshell} (vedi
                          sez.~\ref{sec:shell_scripting}).\\
     \texttt{TERM}      & il tipo di terminale su cui si sta operando (usata
                          per cambiare le formattazioni dei dati stampati
                          laddove esistano specifici supporti).\\ 
     \texttt{USER}      & l'\textit{username} dell'utente.\\
    \hline
  \end{tabular}
  \caption{Le principali variabili di shell.}
  \label{tab:shell_predefined_variables}
\end{table}

\index{variabili!di~ambiente|(}

Una delle altre funzionalità che la shell fornisce con l'uso delle variabili è
quella dell'\textsl{ambiente} (in inglese \textit{environment}). Esso è una
funzionalità messa a disposizione dal sistema che viene usata per poter
utilizzare il valore di alcune \index{variabili!di~shell} variabili di shell
anche all'interno dei programmi che questa mette in esecuzione.\footnote{in
  sostanza quando un programma viene messo in esecuzione dalla \textit{system
    call} \texttt{exec} deve ricevere una serie di informazioni; una parte di
  queste sono gli argomenti, che vengono presi direttamente da quanto scritto
  nella riga di comando con il meccanismo illustrato in precedenza, l'altra
  parte sono appunto le \textsl{variabili di ambiente}, che fanno parte
  dell'\textit{environment}, per una trattazione dettagliata dell'argomento si
  veda sez.~2.3.3 di \cite{GaPiL}.} 

Non tutte le variabili definite nella shell sono però inserite
nell'\textsl{ambiente} in quanto molte di esse (come ad esempio \texttt{PS1})
sono di interesse esclusivo della shell. Se si vuole inserire una variabile
nell'ambiente, ottenendo quella che si suole chiamare una \textsl{variabile di
  ambiente}, lo si deve fare esplicitamente usando il comando interno
\index{comando!built-in!\texttt{export}} \texttt{export} seguito dal nome
della variabile, che deve essere già definita. La \texttt{bash} supporta anche
la definizione della variabile nella stessa linea in cui viene esportata
nell'ambiente, con una sintassi del tipo \texttt{export VAR=val}, questa però
è una estensione che non è supportata da altre shell per cui quando si
scrivono script è il caso di evitare questa sintassi per mantenere la
compatibilità.

Lo stesso risultato si può ottenere con l'uso del comando interno
\index{comando!built-in!\texttt{declare}} \texttt{declare}, che serve in
generale ad assegnare variabili e funzioni (tratteremo queste ultime in
sez.~\ref{sec:shell_scripting}) o impostarne gli attributi. Il comando può
anche essere invocato, con la stessa identica sintassi, come
\index{comando!built-in!\texttt{typeset}} \texttt{typeset}.  Se usato senza
opzioni o argomenti \texttt{declare} mostra la lista delle variabili e
funzioni di shell definite, esattamente come \texttt{set}, in generale però
viene usato passando il nome di una variabile come argomento per impostarne le
caratteristiche tramite una delle opzioni riportate in
tab.~\ref{tab:shell_declare_options}.

Ad esempio si può marcare una variabile come accessibile in sola lettura con
l'opzione \texttt{-r}, o metterla nell'ambiente con l'opzione \texttt{-x}, nel
qual caso il risultato è del tutto equivalente all'uso di \texttt{export}. In
tab.~\ref{tab:shell_declare_options} si sono riportate solo le opzioni
relative alle proprietà delle variabili, il comando opera anche sulle funzioni
di shell (trattate in sez.~\ref{sec:shell_scripting}) e per la documentazione
completa si può fare riferimento alla descrizione nella sezione
``\texttt{SHELL BUILTIN COMMANDS}'' della pagina di manuale.  Per la rimozione
di una variabile dall'ambiente, senza perderne il valore, si può usare invece
la sintassi \texttt{declare +x}.  Si tenga presente infine che se si cancella
una variabile con \texttt{unset} questa viene automaticamente rimossa anche
dall'ambiente.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{-a}& dichiara una variabile vettoriale.\\
     \texttt{-i}& dichiara una variabile intera.\\
     \texttt{-r}& rende la variabile accessibile in sola lettura (e ne
                  impedisce la cancellazione con \texttt{unset}).\\
     \texttt{-x}& inserisce la variabile nell'ambiente.\\
     \texttt{-p}& stampa tutti gli attributi associati ad una variabile o una
                  funzione.\\
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando interno \texttt{declare}.}
  \label{tab:shell_declare_options}
\end{table}

Per visualizzare le variabili di shell presenti nell'ambiente si può usare lo
stesso \texttt{export} senza specificare nulla, e si otterrà la lista delle
variabili presenti nell'ambiente, precedute dalla dichiarazione
``\texttt{declare -x}''; la lista infatti viene stampata in un formato pronto
per essere salvato su un file ed usato come script (tratteremo gli script in
sez.~\ref{sec:shell_scripting}) per ricreare l'ambiente.

Se si vuole solo una semplice lista di nomi con il relativo valore si può
usare il comando \index{comando!\texttt{env}} \texttt{env}. Questo comando in
generale permette di eseguire un altro comando, da passare come argomento,
fornendogli un ambiente modificato rispetto a quello corrente della shell; con
l'opzione \texttt{-i} infatti l'ambiente viene completamente svuotato, mentre
con una serie di opzioni \texttt{-u} si possono cancellare altrettante
variabili di ambiente (da specificare come parametro per l'opzione).  Se si
invoca \texttt{env} senza argomenti il comando si limita a stampare la lista
delle variabili di ambiente, nella classica forma \texttt{VARIABILE=valore}.

Le variabili di ambiente sono di grande importanza perché sono usate in
moltissimi casi per controllare alcuni comportamenti predefiniti dei
programmi. Per questo l'uso di \texttt{env} è in genere una buona misura di
sicurezza per fornire ai comandi che si eseguono un ambiente noto e ben
definito cancellando preventivamente quanto eventualmente presente. Molti
comandi infatti sono controllati anche dai valori delle variabili di ambiente,
ed eseguendoli in un ambiente che può essere stato ``\textsl{manomesso}'' si
potrebbero avere risultati spiacevoli.

Alcune impostazioni e valori di uso generale vengono allora memorizzati in una
serie di variabili che di norma ogni shell deve definire, come \texttt{USER},
che indica il nome dell'utente corrente,
\index{variabili!di~ambiente!\texttt{HOME}} \texttt{HOME} che ne indica la
\textit{home directory}, \index{variabili!di~ambiente!\texttt{TERM}}
\texttt{TERM} che specifica il tipo di terminale su cui si sta operando,
\texttt{LANG} che indica la localizzazione (vedi sez.~\ref{sec:localization})
in uso, \texttt{PATH} che specifica la lista delle directory dove cercare i
comandi; altre variabili sono invece opzionali, ma sono riconosciute dalla
gran parte dei programmi, come \index{variabili!di~ambiente!\texttt{EDITOR}}
\texttt{EDITOR} che indica quale programma usare come editor predefinito o
\texttt{BROWSER} che indica quale navigatore per il web utilizzare.

\index{variabili!di~ambiente|)}
\index{variabili!di~shell|)}

\index{variabili!di~shell!\texttt{IFS}|(}

Una variabile molto importante ma poco nota, ed il cui significato spesso
viene frainteso, è \texttt{IFS}, il cui nome sta per \textit{Internal Field
  Separator}. Questa variabile viene utilizzata per indicare la lista di
caratteri che devono essere considerati come separatori nei risultati di una
\textsl{espansione} di shell ed il suo valore di default è impostato alla
sequenza spazio, tabulatore, ritorno a capo. La variabile è importante perché
ha un effetto diretto, la cui comprensione non è proprio immediata, sul
risultato dell'interpretazione della riga di comando.

Come abbiamo già visto con la \textit{variable expansion} la shell consente di
sostituire automaticamente sulla riga di comando alcune espressioni con il
risultato della relativa \textsl{espansione} (nel caso citato una variabile
con il suo contenuto).  Esistono anche, e le tratteremo a breve, altre
espansioni, come una lista di file ottenuta con l'uso dei caratteri jolly del
\textit{filename globbing}, o il risultato di un calcolo dato da una
\textit{arithmetic expansion} o l'output di un altro comando fornito da una
\textit{command expansion}.

In tutti questi casi il risultato della espansione deve essere di nuovo
sottoposto ad una scansione per suddividerlo in una lista di campi che
verranno interpretati come argomenti o opzioni; questo viene fatto usando come
separatori i caratteri che sono elencati in \texttt{IFS}, in questo modo se si
ha un comando che genera delle liste usando un carattere di separazione che
non rientra nei classici caratteri di spaziatura, si può aggiungerlo a
\texttt{IFS} per usarlo come separatore.

Si tenga presente però che \texttt{IFS} non ha nessun effetto sulla scansione
di una linea di comando ordinaria che non contiene espansioni. Infatti nella
costruzione degli argomenti prima viene effettuata una scansione iniziale, per
la quale vengono usati come separatori solo i caratteri di spaziatura, una
eventuale \textsl{espansione di shell} viene sempre effettuata in un secondo
passo e solo a questo punto possono entrare in gioco i caratteri elencati in
\texttt{IFS}.

\index{variabili!di~shell!\texttt{IFS}|)}

\index{variabili!di~ambiente!\texttt{LANG}|(}

Un'altra variabile di particolare rilevanza è \texttt{LANG}; su Linux infatti
è presente il supporto, attraverso l'uso di una infrastruttura generica che fa
parte delle librerie di sistema, per la localizzazione dei programmi sia in
termini di lingua e set di caratteri utilizzati nella comunicazione con gli
utenti, che per altri aspetti che riguardano convenzioni nazionali, come il
formato dell'ora, della valuta, ecc.  Come spiegato in maggior dettaglio in
sez.~\ref{sec:localization}, questi possono essere scelti in maniera generale
sulla base del valore di questa variabile, o per i singoli aspetti secondo i
valori delle singole variabili a questo deputate (che, come vedremo in
sez.~\ref{sec:localization}, sono tutte nella forma \texttt{LC\_*}).

Al di là della stampa dei vari messaggi in italiano (o in ogni eventuale altra
lingua selezionata) anziché in inglese, uno degli aspetti più significativi
dell'uso di \texttt{LANG}, ed il motivo per cui ne accenniamo anche in questa
sede, è che questa nelle versioni più recenti dei programmi influenza anche le
modalità con cui essi eseguono l'ordinamento alfabetico. Infatti nella
localizzazione di default (quella per cui \texttt{LANG=C}) l'ordine delle
lettere prevede prima tutte le maiuscole e poi tutte le minuscole, cioè
qualcosa del tipo \texttt{ABC...Zabc...z}, mentre ad esempio in italiano
l'ordinamento è completamente diverso e prevede la minuscola seguita della
corrispondente maiuscola, cioè qualcosa del tipo \texttt{aAbBcC...zZ}.

Questo significa che a seconda del supporto o meno per questa funzionalità e
del valore di \texttt{LANG} si possono ottenere risultati completamente
diversi quando i programmi o la shell stessa hanno a che fare con ordinamenti
alfabetici. Pertanto può risultare opportuno, quando si vuole essere sicuri di
avere un comportamento uniforme, impostare forzatamente questa variabile al
valore ``\texttt{C}'' (torneremo sul significato dei valori possibili in
sez.~\ref{sec:localization}) in modo che venga usato sempre il comportamento
di default previsto anche dallo standard POSIX, che è quello che in seguito
considereremo come default.

\index{variabili!di~ambiente!\texttt{LANG}|)}

\index{variabili!di~ambiente!\texttt{PATH}|(}

Di altrettanta se non maggiore rilevanza è la variabile \texttt{PATH} che è
direttamente connessa ad una delle funzionalità della shell su cui finora
abbiamo sorvolato, dandola per scontata: quella del cosiddetto
\itindex{path~search} \textit{path search}, cioè del fatto che la shell
permette di associare automaticamente un nome, scritto sulla linea di comando,
ad un programma da lanciare. In genere, a meno dell'uso degli \textit{alias}
su cui torneremo a breve, questo nome deve corrispondere al nome del file che
contiene il programma che la shell deve eseguire. In sostanza, come visto
nell'esempio iniziale di sez.~\ref{sec:shell_sintax}, si può sempre scrivere
solo il nome del file al posto del pathname completo, se cioè si vuole leggere
una pagina di manuale, basterà scrivere \texttt{man} e non sarà necessario
specificare \texttt{/usr/bin/man}.

Si può fare così perché la shell esegue automaticamente una ricerca nel
cosiddetto \textsl{PATH dei comandi}; cioè dato un nome sulla linea di comando
la shell cerca un file da eseguire con quel nome nella lista di directory
contenute nella variabile d'ambiente \texttt{PATH}.  Se si vuole evitare
questo comportamento, ad esempio perché il programma che si vuole lanciare non
è in una di quelle directory e non sarebbe trovato, è necessario specificare,
sia in forma assoluta che relativa, il pathname per accedere al comando, la
shell riconosce che si vuole fare questo quando nel nome del comando compare
il carattere ``\texttt{/}'', che indica una directory. Ad esempio per lanciare
un comando (o uno script) nella directory corrente si usa la sintassi:
\begin{Example}
./comando
\end{Example}

La variabile \texttt{PATH} ha la forma di una lista di pathname di directory,
separati fra loro da un carattere di due punti, un formato comune usato nelle
variabili di ambiente tutte le volte che si deve specificare una lista di
directory in cui effettuare ricerche (lo reincontreremo spesso, ad esempio in
sez.~\ref{sec:cfg_dyn_lib} per le directory dove sono mantenute le librerie di
sistema). Un esempio del valore di questa variabile potrebbe essere il
seguente:
\begin{Example}
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
\end{Example}
come è presa dalla definizione standard per un utente comune su Debian. Si
noti come in questo caso siano indicate solo le directory che, nella
standardizzazione del filesystem illustrata in sez.~\ref{sec:file_FHS},
contengono i programmi di uso per l'utente; sono pertanto assenti directory
come \texttt{/sbin}, \texttt{/usr/sbin}, ecc. che usualmente vengono inserite
dentro \texttt{PATH} soltanto per l'amministratore.  

Questo è il motivo per cui alcuni comandi ``\textsl{non funzionano}'' quando
chiamati da utente normale, in realtà non è che non funzionano, solo non
vengono trovati i relativi programmi, che potrebbero tuttavia essere eseguiti
ugualmente (con privilegi ridotti ovviamente) usando un pathname assoluto o
inserendo le directory in cui si trovano all'interno di \texttt{PATH}.

Si tenga conto che \texttt{PATH} è comunque modificabile dall'utente, che può
personalizzarla a piacere, ed aggiungere un'altra directory, come ad esempio
la directory corrente, che di norma non vi è mai inclusa.  Questa scelta ha
una ragione precisa: se tenete dentro \texttt{PATH} la directory corrente un
altro utente potrebbe mettere nelle directory cui ha accesso una versione
``\textsl{opportunamente}'' modificata di un comando di sistema, che verrebbe
eseguita al posto dell'originale, col rischio di guai seri qualora ciò
avvenisse per l'amministratore; è vero che se si inserisce la directory
corrente in coda a \texttt{PATH} i comandi standard hanno la precedenza, ma
qualcuno potrebbe sempre creare un programma \texttt{la} e aspettarvi al varco
per un comune errore di battitura di \texttt{ls}.

Qualora si voglia cambiare \texttt{PATH} il dubbio casomai può essere sul come
farlo senza doversi riscrivere tutto da capo il contenuto precedente; per
questo ci viene di nuovo in aiuto la sintassi della riga di comando, per cui è
possibile ridefinire una qualunque variabile con una espressione del tipo:
\begin{Example}
PATH=$PATH:./
\end{Example}
%$
dove di nuovo si è usata la capacità della shell di \textsl{espandere} il
valore delle variabili, che funziona anche all'interno della sintassi usata
per assegnare le stesse.  Si noti come una riga del genere non esegua nessun
programma, limitandosi ad utilizzare esclusivamente le funzionalità interne
della shell. Una delle caratteristiche peculiari di \texttt{bash} è quella di
essere in grado di vedere immediatamente i nuovi programmi non appena si
ridefinisce il valore di \texttt{PATH}, mentre con altre shell (ad esempio la
\texttt{csh}) può essere necessario utilizzare un apposito comando interno
(nel caso \texttt{rehash}).

Come complemento alla gestione del \textit{path search} la shell fornisce il
comando interno \index{comando!\texttt{which}} \texttt{which} che, dato il
nome di un programma presente nel \textit{path search}, ne stampa a video il
pathname assoluto, ad esempio potremo ottenere il pathname del comando
\texttt{ls} con:
\begin{Console}
piccardi@hain:~/Truelite$ \textbf{which ls}
/bin/ls
\end{Console} 
%$
in questo modo è possibile anche capire quale sia effettivamente il programma
che viene usato qualora ne esistano più versioni in alcune delle directory
contenute all'interno di \texttt{PATH}. La regola è che viene usato sempre il
primo programma che viene trovato nella scansione delle directory del
\textit{path search}; questa avviene da sinistra a destra nell'ordine in cui
le directory sono elencate all'interno di \texttt{PATH}. Se non viene trovato
nessun programma corrispondente, non sarà stampato nulla.

\index{variabili!di~ambiente!\texttt{PATH}|)}

Si tenga presente però che \texttt{which} funziona controllando se il nome
passato come argomento compare nella lista dei programmi contenuti nelle
directory elencate in \texttt{PATH}, se si indica il nome di un comando
interno della shell questo non viene considerato. Per questo, se si vuole
capire se si sta usando un comando interno o un programma o un \textit{alias}
(che tratteremo a breve) si deve usare un altro comando interno,
\index{comando!built-in!\texttt{type}} \texttt{type}, nel qual caso otterremo
qualcosa del tipo:
\begin{Console}
piccardi@hain:~/Truelite$ \textbf{type export}
export is a shell builtin
\end{Console}
%$

Un'ulteriore funzionalità che la shell mette a disposizione è quella degli
\textit{alias}: prima ancora di cercare se il nome di un comando corrisponde
ad un programma presente in una delle directory indicate in \texttt{PATH}, la
shell controlla se esso corrisponde ad un \textit{alias}; ci permette così di
ideare nuovi comandi, definire abbreviazioni per quelli più usati, o
ridefinire lo stesso nome di un comando per farlo comportare in maniera
diversa.  

Un \textit{alias} si crea con il comando interno
\index{comando!built-in!\texttt{alias}} \texttt{alias} associando un nome ad
un altro comando (che può a sua volta essere stato definito in un altro
\textit{alias}) con una sintassi del tipo:
\begin{Example}
alias ll='ls --color=auto  -l'
\end{Example}
ma si può anche definire una abbreviazione con:
\begin{Example}
alias l='ls -l'
\end{Example}
o ridefinire un comando esistente con:
\begin{Example}
alias rm='rm -i'
\end{Example}

In questo modo nel primo caso si definisce una versione colorata e
``\textsl{prolissa}'' di \texttt{ls}, nel secondo una abbreviazione per l'uso
di \texttt{ls -l} e nel terzo si ridefinisce \texttt{rm} in modo che di
default sia richiesta conferma nella cancellazione dei file. Per cancellare un
\textit{alias} si può usare il comando
\index{comando!built-in!\texttt{unalias}} \texttt{unalias} seguito dal nome
dello stesso.  Qualora invece si esegua il comando \texttt{alias} senza
specificare nulla questo mostrerà la lista degli \textit{alias} già definiti.

\itindbeg{filename~globbing}

Un'altra funzionalità di grande utilità fornita dalla shell è il cosiddetto
\textit{filename globbing}. Si può cioè operare su insiemi di file con nomi
simili passando ai comandi che dovranno operare su di essi degli argomenti che
li indicano in gruppo, tramite i cosiddetti \textsl{caratteri jolly} (in
inglese \textit{wildcard}).  Se cioè all'interno di una riga di comando si usa
come argomento una espressione che contiene uno di questi caratteri jolly, la
shell lo interpreterà come una richiesta di \textit{filename globbing} ed
interpreterà quella espressione come indicante un insieme di file.

Il meccanismo prevede che la shell verifichi quali file corrispondono
all'espressione e la \textsl{espanda} in una lista che verrà passata al
comando al posto del singolo argomento. Normalmente la ricerca viene fatta
nella directory corrente ma si può usare il carattere ``\texttt{/}'' per
indicare un \textit{pathname} e fare riferimento ad altre directory.

Come nel caso del DOS o del VMS, il carattere ``\texttt{*}'' indica un numero
arbitrario di caratteri qualsiasi mentre il carattere ``\texttt{?}'' indica un
solo carattere qualunque.  Ma oltre a queste due \textit{wildcard} elementari
la shell ne supporta alcune più sofisticate. Ad esempio si possono indicare
elenchi di possibili alternative per un singolo carattere, ponendole fra due
parentesi quadre. Le alternative possono anche essere espresse con una lista
dei caratteri voluti messi uno di seguito all'altro, mentre si possono
specificare degli intervalli (corrispondenti a tutti i caratteri compresi fra
i due estremi) usando due caratteri separati da un ``\texttt{-}''. 

In questo caso però occorre fare attenzione al tipo di ordinamento alfabetico
dovuto alle diverse localizzazioni, perché a seconda di questo si potranno
ottenere risultati diversi a causa della diversa interpretazione
dell'intervallo, ad esempio in italiano l'intervallo \texttt{[a-z]}
corrisponde a tutte le lettere maiuscole e minuscole tranne la ``\texttt{Z}''
mentre in inglese corrisponderebbe a tutte le minuscole.  Nel seguito si farà
riferimento al comportamento di default dettato dallo standard POSIX, relativo
al caso in cui \texttt{LANG=C} (per ulteriori dettagli si rimanda a
sez.~\ref{sec:localization}).

Si può inoltre invertire la selezione dei caratteri specificati fra parentesi
quadre precedendo la lista o l'intervallo con un carattere di ``\verb|^|''.
Infine come ultima modalità di espansione si può utilizzare il carattere
``\verb|~|'' per indicare la home directory dell'utente corrente, mentre si
può usare la notazione \verb|~username| per indicare la home directory di un
altro utente. Infine qualora l'espressione non corrisponda a nessun file essa
verrà passata letteralmente al comando, con in genere il risultato di ottenere
un errore di file non esistente.

Per capire meglio facciamo alcuni esempi di \textit{filename globbing}:
supposto che per essi venga usata la solita estensione \texttt{.tex}, si
potranno vedere tutti i sorgenti Latex presenti in una directory con una riga
di comando come:
\begin{Console}
piccardi@anarres:~/truedoc/sicurezza$ \textbf{ls *.tex}
cryptoapp.tex  firewall.tex  ids.tex  introsec.tex  sicurezza.tex
\end{Console}
%$
mentre si potranno selezionare tutti i file il cui nome è lungo esattamente
sette caratteri con una riga di comando del tipo:
\begin{Console}
piccardi@anarres:~/truedoc/sicurezza$ \textbf{ls ???????}
ids.aux  ids.tex
\end{Console} 
%$
se invece vogliamo vedere i file i cui nomi finiscono in \texttt{c} o in
\texttt{g} potremo usare:
\begin{Console}
piccardi@anarres:~/truedoc/sicurezza$ \textbf{ls *[cg]}
firewall.log  sicurezza.blg  sicurezza.log
firewall.toc  sicurezza.ilg  sicurezza.toc
\end{Console} 
%$
mentre per selezionare i file il cui nome inizia con una lettera maiuscola
potremo usare:
\begin{Console}
piccardi@anarres:~/truedoc/sicurezza$ \textbf{ls [A-Z]*}
Makefile  SicurezzaGL.txt  TODO
\end{Console} 
%$
infine se ci interessano i file LaTeX il cui nome non inizia con una lettera
minuscola fra ``\texttt{d}'' e ``\texttt{r}'' potremo usare:
\begin{Console}
piccardi@anarres:~/truedoc/sicurezza$ \textbf{ls [^d-r]*.tex}
cryptoapp.tex  sicurezza.tex
\end{Console} 
%$

Si tenga presente che il meccanismo del \textit{filename globbing} opera
esattamente nella modalità descritta, sostituendo all'espressione sulla riga
di comando il suo risultato, per cui al comando verranno passati come
argomenti i nomi dei file che vi corrispondono, o il nome, se è uno solo, o la
stringa letterale se niente corrisponde. Questo comporta che il risultato poi
dipenderà da come il comando interpreta gli argomenti che riceve, cosa che
alle volte può causare risultati non troppo intuitivi. Ad esempio si fosse
usata la seguente riga di comando:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{ls ??????}
IPSEC_modes.dia    esp_scheme.pdf  iptraf5.png         openvpn.dia
IPSEC_modes.eps    etherape1.eps   iptraf6.eps         openvpn.eps
IPSEC_modes.pdf    etherape1.png   iptraf6.png         openvpn.pdf
...
\end{Console} 
%$
si sarebbe ottenuto un risultato forse inaspettato, dato che non riporta file
di sei lettere. Il risultato è questo perché l'unico nome di file di sei
lettere presente nel caso dell'esempio è quello della directory
\texttt{images}, per cui dall'espansione del \textit{filename globbing}
otteniamo una riga di comando equivalente a ``\texttt{ls images}''; quindi ci
verrà stampato, secondo la sintassi di \texttt{ls}, il contenuto di tale
directory.

Il \textit{filename globbing} e l'uso delle variabili di ambiente sono
funzionalità molto utili, però talvolta presentano degli inconvenienti. Ad
esempio se si volesse passare ad un comando come argomento un file il cui nome
contiene uno dei caratteri jolly, o il carattere ``\texttt{\$}'' usato per
referenziare le variabili, si avrebbe il problema che la shell cercherebbe di
espandere la relativa espressione.  Un inconveniente analogo ci sarebbe per i
nomi dei file che contengono degli spazi: dato che lo spazio viene usato per
separare fra di loro gli argomenti, un tale nome verrebbe spezzato in due con
il risultato di passare al comando due argomenti invece di uno.

Per risolvere questi problemi esistono dei caratteri che permettono di
disabilitare del tutto o in parte le capacità della shell di interpretare in
maniera speciale altri caratteri. Uno di questi è la barra trasversa
``\texttt{\bslash}'' che anteposta ad un carattere qualsiasi ne disabilita
l'interpretazione, così si può usare un asterisco in un argomento indicandolo
con ``\texttt{\bslash*}'' o si può utilizzare uno spazio proteggendolo con
``\verb*|\ |'' o specificare la stessa barra trasversa con
``\texttt{\bslash\bslash}'' ed anche, come accennato in precedenza, proteggere
il carattere di ritorno a capo, che di norma viene usato come terminazione
della riga di comando.

Una modalità alternativa è quella che permette di specificare degli argomenti
che vanno considerati come una stringa letterale (risolvendo anche così il
problema degli spazi) e per i quali non si vuole che la shell effettui delle
espansioni. Questo può essere fatto in due modi, il primo, che disabilita il
\textit{filename globbing} e l'interpretazione degli spazi, è quello di
definire la stringa racchiudendola fra virgolette (usando cioè il carattere
``\verb|"|''), così che al suo interno si possano usare spazi, asterischi e
punti interrogativi.  In questo modo però resta attiva l'espansione di
eventuali variabili di shell tramite il carattere ``\texttt{\$}''. Si può
eliminare anche questa se al posto delle virgolette si usano gli apici singoli
(cioè il carattere ``\verb|'|''); in tal caso la stringa sarà interpretata in
maniera assolutamente letterale.

\itindend{filename~globbing}
\itindbeg{command~expansion}

Un'altra funzionalità molto utile della shell è quella che viene chiamata
\textit{command expansion}; si può cioè usare come argomento sulla riga di
comando il risultato ottenuto con un'altra riga di comando. Per fare questo si
hanno a disposizione due sintassi equivalenti; la prima prevede che si
racchiuda il comando da eseguire fra due apici inversi (usando cioè il
carattere ``\verb|`|''), la seconda che si usi il costrutto
\texttt{\$(comando)}; ad esempio se nel file \texttt{elenco} si è scritto una
lista di file si potrà effettuarne la cancellazione con una linea di comando
come:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{rm `cat elenco`}
rm: cannot lstat `pippo.tex': No such file or directory
rm: cannot lstat `vecchio.tex': No such file or directory
\end{Console} 
%$
che nel caso fallisce perché i file elencati non esistono. 

In questo caso quello che succede è che la shell esegue il comando racchiuso
fra apici inversi, e mette il suo output sulla riga di comando, come se lo si
fosse scritto manualmente.  Questa in realtà è una semplificazione, per essere
precisi quello che avviene è che l'uscita del programma viene scansionata
usando i caratteri di \texttt{IFS} come separatori e poi ``\textsl{espansa}''
in un elenco di argomenti per il programma.  La \textit{command expansion} ci
mette a disposizione un mezzo estremamente potente per collegare fra loro i
comandi: possiamo usare il risultato di uno di essi per generare gli argomenti
di un altro.

\itindend{command~expansion}
\itindbeg{arithmetic~expansion}

Simile alla \textit{command expansion} è la cosiddetta \textit{arithmetic
  expansion} che permette di effettuare dei semplici calcoli numerici. Per
farlo si usa una sintassi del tipo di \texttt{\$((espressione))}, dove con
\texttt{espressione} si indica una espressione aritmetica da
calcolare. L'espressione usa numeri interi e gli stessi operatori aritmetici
usati dal linguaggio C come \texttt{+}, \texttt{-}, \texttt{*} e \texttt{/},
la descrizione completa di tutti gli operatori e della sintassi delle
espressioni aritmetiche è disponibile nella pagina di manuale della
\texttt{bash}, alla sezione ``\texttt{ARITHMETIC EVALUATION}''. Il risultato
del calcolo sarà riportato direttamente come argomento, e potremo avere un
qualcosa del tipo:
\begin{Console}
piccardi@hain:~/truedoc/corso$ \textbf{echo $((5+7))}
12
\end{Console} 
e considerato che all'interno dell'espressione si può usare sia la
\textit{variable expansion} che la \textit{command expansion}, si capisce
anche come da questa espansione si possano trarre ulteriori potenzialità di
utilizzo.

\itindend{arithmetic~expansion}

\itindbeg{history}

L'ultima funzionalità della shell che prenderemo in esame è quella della
\textsl{storia dei comandi}, la cosiddetta \textit{history}, che permette di
accedere, usando i tasti di freccia in alto e in basso, alle linee di comando
eseguite in precedenza. La \texttt{bash} infatti mantiene in memoria le linee
di comando che ha eseguito e poi quando esce salva l'elenco in un apposito
file.

Di default la storia dei comandi viene salvata nel file
\texttt{.bash\_history} nella home dell'utente, ma questo può essere cambiato
in qualunque altro file specificato dalla variabile
\index{variabili!di~shell!\texttt{HISTFILE}} \texttt{HISTFILE}. La shell di
default mantiene in memoria un massimo di 500 comandi, ma questo valore può
essere modificato specificando un nuovo default nella variabile
\index{variabili!di~shell!\texttt{HISTSIZE}} \texttt{HISTSIZE}, si può anche
indicare una dimensione massima in righe del file \texttt{.bash\_history} con
la variabile \index{variabili!di~shell!\texttt{HISTFILESIZE}}
\texttt{HISTFILESIZE}.

\itindbeg{history~expansion|(}

Diventa così possibile non solo rieseguire i comandi precedenti, navigando
avanti ed indietro lungo la storia con i tasti di freccia in alto e in basso,
ma è anche possibile effettuare una ricerca incrementale nella
\textit{history} utilizzando la combinazione \texttt{C-r} seguita dal testo
della ricerca (il cui risultato comparirà all'interno di un apposito
\textit{prompt}).  Inoltre con l'uso del carattere ``\texttt{!}'' diventa
possibile richiamare una specifica voce sulla riga di comando stessa,
indicandola sia per numero che tramite le prime lettere, secondo le modalità
illustrate in tab.~\ref{tab:history_expansion}, utilizzando quella che viene
chiamata  \textit{history expansion}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Sintassi} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{!!}      & richiama il comando più recente.\\
     \texttt{!n}      & richiama il comando numerato \texttt{n} nella
                        \textit{history}.\\ 
     \texttt{!-n}     & richiama il comando precedente di \texttt{n} posizioni
                        nella \textit{history}.\\
     \texttt{!string} & richiama l'ultimo comando eseguito che inizia per 
                        \texttt{string}.\\
     \texttt{!?string}& richiama l'ultimo comando eseguito che contiene la
                        stringa \texttt{string}.\\
     \texttt{\circonf string\circonf subst}& 
                        richiama il comando precedente sostituendo
                        \texttt{string} con \texttt{subst}.\\ 
    \hline
  \end{tabular}
  \caption{Le modalità di utilizzo della \itindex{history~expansion}
    \textit{history expansion}.} 
  \label{tab:history_expansion}
\end{table}

Con il comando \index{comando!built-in!\texttt{history}} \texttt{history}
inoltre si può visualizzare l'intero contenuto della \textit{history}, in cui
ogni riga è numerata progressivamente, con il valore che si può usare con
``\texttt{!}''  per richiamarla. Così ad esempio per richiamare righe di
comando precedenti si potrà fare qualcosa come:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{which chown}
/bin/chown
piccardi@anarres:~/truedoc/corso$ \textbf{ls -l $(!wh)}
ls -l $(which chown)
-rwxr-xr-x    1 root     root        19948 Aug 19 03:44 /bin/chown
\end{Console}
%$
mentre se si vuole usare direttamente il numero, si potrà verificarlo con:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{history}
...
  523  ls [^d-r]*.tex
  524  which chown
  525  ls -l $(which chown)
  526  history
\end{Console}
e richiamare un comando con:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{!526}
...
  523  ls [^d-r]*.tex
  524  which chown
  525  ls -l $(which chown)
  526  history
  527  history
\end{Console}

Si tenga infine conto che il carattere ``\texttt{!}'', come mostrato nel primo
esempio, viene espanso quando usato nella linea di comando, e per usarlo in
maniera letterale occorre o proteggerlo con la barra rovesciata, o metterlo in
una stringa delimitata da apici singoli. Per maggiori dettagli riguardo tutto
l'argomento si può fare riferimento alla sezione ``\texttt{HISTORY
  EXPANSION}'' del manuale della shell.

\itindbeg{history~expansion|)}

Concludiamo questa sezione relativa alla funzionalità di base della shell con
una panoramica più estesa sull'uso interattivo della riga di comando, ed in
particolare sulle cosiddette ``\textsl{scorciatoie da tastiera}'' disponibili.
Dato che la gran parte di queste attengono proprio all'uso della
\textit{history} ci è parso opportuno trattarle dettagliatamente a questo
punto.

\itindend{history}

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Combinazione} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{C-r} & ricerca incrementale nella history.\\
     \texttt{C-a} & spostamento a inizio riga.\\
     \texttt{C-e} & spostamento a fine riga.\\
     \texttt{C-u} & cancellazione da posizione corrente a inizio riga.\\
     \texttt{C-k} & cancellazione da posizione corrente a fine riga.\\
     \texttt{C-y} & inserisce l'ultimo testo cancellato.\\
     \texttt{M-b} & spostamento indietro di una parola.\\
     \texttt{M-f} & spostamento avanti di una parola.\\
     \texttt{C-l} & ripulitura e posizionamento in testa allo schermo.\\
     \texttt{Tab} & esegue l'\textsl{autocompletamento} del testo corrente.\\
    \hline
  \end{tabular}
  \caption{Le scorciatoie da tastiera per l'\textit{editing} di linea.} 
  \label{tab:shell_line_editor}
\end{table}

Abbiamo visto in sez.~\ref{sec:struct_job_control} come alcune combinazioni di
tasti (vedi tab.~\ref{tab:terminal_control_key}) siano collegate, grazie
all'interfaccia dei terminali, all'emissione di segnali o altre funzionalità
che consentono di controllare il comportamento dell'interfaccia a riga di
comando. La shell stessa poi supporta, come per il \texttt{C-r} di cui abbiamo
appena parlato, l'uso di altre combinazioni di tasti che consentono di
effettuare modifiche sulla riga di comando che si sta scrivendo; ad esempio
con \texttt{C-a} si può andare a inizio riga e con \texttt{C-e} a fine riga.

Queste funzionalità derivano in realtà da una libreria di gestione chiamata
appunto \textit{readline} che consente di operare in maniera generica su una
riga di terminale, spostandosi modificando e cancellando parti utilizzando una
serie di combinazioni di tasti che possono essere configurate nei dettagli
(torneremo su questo in sez.~\ref{sec:shell_operation_modes}) ma che di
default usano le stesse convenzioni dell'editor \texttt{emacs} che
illustreremo brevemente in sez.~\ref{sec:emacs-e-xemacs}.  

Si sono riportate le principali combinazioni di tasti forniti da questa
libreria in tab.~\ref{tab:shell_line_editor}. Nella tabella con ``\texttt{M}''
si intende il tasto \textit{alt}, la notazione con cui vengono espresse le
combinazioni di tasti verrà trattata più dettagliatamente in
sez.~\ref{sec:emacs-e-xemacs}.  Per l'elenco completo di tutte le funzionalità
si può consultare la sezione ``\texttt{Readline Command Names}''della pagina
di manuale della shell.

Una di queste funzionalità però, quella dell'\textit{autocompletamento} con
l'uso del tasto di tabulazione, merita di essere illustrata a parte, in quanto
costituisce una delle caratteristiche più avanzate della \texttt{bash}. La
shell infatti supporta nativamente il completamento dei comandi e dei nomi dei
file che si scrivono sulla riga di comando. Basta cioè inserire le prime
lettere di un comando e premere il tabulatore per avere il completamento del
nome del comando, o, se c'è ambiguità con più completamenti possibili, il
completamento della parte non ambigua; in quest'ultimo caso inoltre, premendo
il tabulatore due volte di fila, si potrà avere la lista dei completamenti
possibili. 

Questo meccanismo funziona di default con i programmi per la prima parola
scritta sulla riga di comando, e con i nomi dei file per le parole successive,
ma la vera potenza della shell è che l'autocompletamento è completamente
programmabile (si consulti la sezione ``\texttt{Programmable Completion}''
della pagina di manuale) e può essere esteso nelle modalità più varie. La gran
parte delle distribuzioni definisce una serie di queste estensioni nel file
\index{configurazione!\texttt{/etc/bash\_completion}}
\texttt{/etc/bash\_completion}, usando il quale diventa possibile ottenere
completamenti, anche molto complessi, sui possibili argomenti e opzioni di
vari comandi.


\subsection{La redirezione dell'I/O}
\label{sec:shell_IO_redirect}

\itindbeg{standard~input}
\itindbeg{standard~output}
\itindbeg{standard~error}

Si è dedicata una sezione separata a questa funzionalità della shell per la
sua particolare rilevanza, dato che è proprio la redirezione delle operazioni
di I/O che ci permette di costruire quella catena di montaggio di cui abbiamo
parlato in sez.~\ref{sec:shell_design}, che consente di combinare le capacità
dei vari comandi ed ottenere l'effettiva potenza della riga di comando.

Come accennato in sez.~\ref{sec:struct_job_control} in un sistema unix-like i
programmi si aspettano di avere disponibili e già aperti tre file:
\textit{standard input}, lo \textit{standard output} e lo \textit{standard
  error}.  Seguendo una convenzione comune, i comandi si aspettano di ricevere
i loro dati in ingresso sullo \textit{standard input} (e non da uno specifico
file o dispositivo, a meno che questo non sia previsto come argomento), mentre
scrivono i loro dati in uscita sullo \textit{standard output}.  Lo
\textit{standard error} in caso di operazioni regolari non viene mai usato; su
di esso vengono scritti solo gli eventuali messaggi di errore.

Quando si usa l'interfaccia a riga di comando \textit{standard input},
\textit{standard output} e \textit{standard error} vengono aperti nella
procedura di accesso al sistema e sono tutti associati al terminale su cui
viene eseguita la shell.  Dato che, come accennato in
sez.~\ref{sec:struct_proc_architecture}, i file aperti vengono ereditati dai
processi figli, normalmente quando la shell lancia un comando questi file
restano gli stessi anche per lui, che pertanto potrà ricevere i dati in
ingresso dalla tastiera e scrivere i suoi risultati sullo schermo.

Gli eventuali errori vanno anch'essi sul terminale e compaiono sullo schermo
insieme ai dati in uscita, ma questo avviene solo perché si è usato lo stesso
file dello \textit{standard output}. In generale, ad esempio quando si
redirige lo \textit{standard output} come vedremo fra poco, non è così essendo
i due file distinti, per cui si potrà mandare l'uscita di un comando su un
file mentre gli errori resteranno sul terminale. La \textsl{redirezione
  dell'I/O} infatti è la capacità della shell di modificare, per il processo
figlio con cui esegue un comando, i file a cui fanno riferimento lo
\textit{standard input}, lo \textit{standard output} e lo \textit{standard
  error}, così che esso possa ricevere dati in ingresso o scrivere dati in
uscita ed errori su degli altri file e non sul terminale.

Per capire meglio il significato della redirezione prendiamo come esempio il
comando \index{comando!\texttt{cat}} \texttt{cat}. Questo è un comando
elementare che serve a leggere uno o più file in ingresso, passati come
argomenti, e a scriverne il contenuto sullo \textit{standard output}. Se non
si specifica nessun file come argomento il comando legge di default dallo
\textit{standard input}, per cui se eseguiamo:
\begin{Console}
piccardi@anarres:~$ \textbf{cat}

\end{Console}
%$
ci troveremo in una situazione in cui il comando si blocca sulla riga
successiva in attesa che scriviamo qualcosa sul terminale. Se lo facciamo
scrivendo \texttt{prova} seguito da invio otterremo qualcosa del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{cat}
\textbf{prova}
prova
\end{Console}
%$
dove il comando reagisce all'invio ristampando sul terminale quanto appena
scritto e attendendo nuovi dati in ingresso. 

Questo avviene in quanto sul terminale si ha quello che si chiama \textit{I/O
  bufferizzato} ed i dati in ingresso vengono letti e scritti una riga alla
volta, per cui alla pressione dell'invio verrà letto quanto appena scritto, ed
il comando lo riscriverà sullo \textit{standard output}; per uscire dal
comando occorre nel caso indicare che la lettura è conclusa, ad esempio
inviando un end-of-file sull'input con \texttt{C-d}, o interrompere il
programma con un segnale.

Usato così il comando non è di grande utilità, dato che in genere non serve a
molto scrivere qualcosa sulla tastiera per vederselo ristampare sul terminale
ad ogni riga; però se vogliamo vedere il contenuto di un file il modo più
immediato per farlo è con un comando del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{cat /etc/profile}
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).

PATH="/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games"
...
\end{Console}
%$
dato che il comando leggerà il contenuto del file e lo riverserà sullo
\textit{standard output}, ed essendo quest'ultimo collegato al terminale, lo
si vedrà sullo schermo.

Fin qui l'utilità del comando è relativa, dato che programmi per visualizzare
il contenuto del file ce ne sono altri, magari più sofisticati come
\texttt{more} e \texttt{less}, che permettono anche di vedere il file un pezzo
alla volta, e andare avanti e indietro, senza scrivere tutto il file in un
colpo solo sul terminale, per cui l'inizio va perso nello scorrimento dello
schermo. Il comando comunque prende alcune opzioni per facilitare la
visualizzazione, come \texttt{-n} che stampa un numero progressivo per ogni
riga, \texttt{-t} che stampa i tabulatori come \verb|^I|, \texttt{-v} che
visualizza i caratteri non stampabili, e \texttt{-E} che scrive un \texttt{\$}
alla fine di ogni riga. La descrizione completa si trova al solito nella
pagina di manuale, accessibile con \texttt{man cat}.

Ma la vera utilità di \texttt{cat}, il cui scopo in realtà non è quello di
mostrare il contenuto di un file, emerge solo quando esso viene unito alla
capacità della shell di modificare i file associati a \textit{standard input},
\textit{standard output} e \textit{standard error}, cioè con la
\textsl{redirezione dell'I/O}.  Per fare questo la shell riconosce sulla riga
di comando alcuni caratteri che svolgono la funzione di operatori, detti
appunto \textsl{operatori di redirezione}.  I due operatori più elementari
sono ``\texttt{<}'' e ``\texttt{>}'' che permettono rispettivamente di
redirigere lo \textit{standard input} e lo \textit{standard output} sul file
specificato dall'utente dopo l'operatore.

In realtà si può effettuare la redirezione di un qualunque file descriptor
usato da un programma, specificando il suo numero prima dell'operatore, questo
comporta ad esempio che per redirigere lo \textit{standard error} si usa
l'operatore ``\texttt{2>}'' dato che esso è associato al file descriptor 2, ma
si potrebbe utilizzare allo stesso modo ``\texttt{3>}'' per redirigere il file
descriptor 3; i dettagli sulle varie forme di redirezione si possono trovare
nella pagina di manuale alla sezione ``\texttt{REDIRECTION}''.

Cominciamo allora a vedere come si usano questi due operatori. Una modalità
alternativa di stampare il contenuto di un file con \texttt{cat} è utilizzare
un comando del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{cat < /etc/profile}
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
...
\end{Console}
%$
in cui invece di leggere un file specificato come argomento sulla riga di
comando (si noti che qui \texttt{cat} non ha argomenti, il nome del file è
dopo il carattere ``\texttt{<}''), si torna a leggere dallo \textit{standard
  input} che però in questo caso, invece di essere associato al terminale, è
stato rediretto dall'operatore ``\texttt{<}'' su \texttt{/etc/profile}, per
cui si otterrà il contenuto di questo file.

La redirezione dell'output avviene in maniera identica associando con
``\texttt{>}'' lo \textit{standard output} ad un file. Ad esempio si potrà
copiare il contenuto del file \texttt{pippo} sul file \texttt{pippo2}
utilizzando un comando del tipo:
\begin{Example}
cat pippo > pippo2
\end{Example}
dato che con questa redirezione invece che sul terminale il contenuto di
\texttt{pippo} sarà scritto su \texttt{pippo2}.

Fin qui niente di particolarmente utile, dato che nel primo caso si sarebbe
potuto leggere direttamente il file, mentre nel secondo si sarebbe potuto
usare direttamente \texttt{cp}. Però, e qui emerge anche la vera utilità del
comando \texttt{cat}, con \texttt{cp} si può solo copiare il contenuto di un
file su un altro, ma cosa succede invece se con \texttt{cat} specifichiamo
come argomenti una serie di file da leggere e poi redirigiamo l'uscita su di
un altro file?

Per quanto abbiamo detto in questo caso \texttt{cat} leggerà il contenuto di
ciascuno dei file passati come argomenti, riscrivendo il tutto sullo
\textit{standard output}.  Avendo rediretto lo \textit{standard output} su un
altro file il risultato sarà che quest'ultimo avrà come contenuto la
\textsl{concatenazione} del contenuto di tutti i file passati come argomenti a
\texttt{cat}, ed infatti il nome del comando, non proprio intuitivo, deriva da
\textit{con\textbf{cat}enate file}.

Così se si è spezzato un file di grosse dimensioni in una serie di file più
piccoli (ad esempio per scriverlo su una serie di CD) si potrà ricostruirlo
con un semplice comando del tipo:
\begin{Example}
cat pezzo1 pezzo2 pezzo3 ... > filecompleto
\end{Example}

La redirezione dello \textit{standard input} è invece molto utile con i
programmi che richiedono l'immissione dei dati da tastiera, specie quando
questi vengono eseguiti in uno script. Una volta definiti quali dati sono
necessari infatti li si potranno scrivere in un file, e farli leggere al
programma semplicemente con la redirezione dello \textit{standard input}.

Si tenga conto che quando si effettua la redirezione dello \textit{standard
  output} se il file su cui la si esegue non esiste esso viene creato, mentre
se esiste il suo contenuto viene sovrascritto, a meno che non si sia bloccato
questo comportamento indicando alla shell di segnalare un errore con
\texttt{set -C} (vedi tab.~\ref{tab:shell_set_options}), occorre pertanto
stare molto attenti a non cancellare dei dati. Per questo è bene essere
consapevoli della modalità con cui il meccanismo funziona, se infatti si
pensasse di aggiungere dei dati in fondo ad un file con un comando del tipo
di:
\begin{Example}
cat file addendum > file
\end{Example}
si potrebbe andrebbe incontro ad una sgradita sorpresa. 

Quello che avviene con la redirezione infatti è che se un file esiste questo
prima viene ``\textsl{troncato}'',\footnote{esiste una apposita funzione di
  sistema (per i dettagli si può consultare sez.~4.3.3 di \cite{GaPiL}) che
  consente di \textsl{accorciare} a piacere la dimensione di un file; per
  evitare sovrascritture parziali di contenuti già esistenti effettuando una
  redirezione il file di destinazione viene preventivamente troncato a
  lunghezza nulla.} e poi ci viene scritto sopra. Il che comporta che
nell'esempio in questione \texttt{cat}, alla lettura di \texttt{file}, lo
troverebbe vuoto.  Nell'esempio citato \texttt{cat} è in grado di rilevare la
situazione anomala e stampare un errore, ma non è detto che altri programmi (o
altre versioni di \texttt{cat}) siano in grado di farlo; se ad esempio si
fosse usato \texttt{less} (che usato con la redirezione si comporta
esattamente come \texttt{cat}) si sarebbe perso il contenuto originale di
\texttt{file}.

Per ovviare a questo problema è disponibile un altro operatore di redirezione,
``\verb|>>|'', che redirige lo \textit{standard output} su di un file
eseguendo però la scrittura in ``\textit{append}'', una modalità di scrittura
speciale in cui i dati vengono aggiunti in coda a quelli già presenti. In
questo modo si può realizzare l'aggiunta di informazioni alla fine del file
\texttt{file} con il comando:
\begin{Example}
cat addendum >> file
\end{Example}

Si tenga presente che avere eseguito la redirezione dello \textit{standard
  output} non comporta il fatto che un programma a questo punto non scriva più
nulla sul terminale, si ricordi infatti che gli errori vengono scritti sullo
\textit{standard error}, che essendo un file diverso non verrà rediretto; se
pertanto si verificano errori nell'esecuzione di un comando i relativi
messaggi continueranno ad essere stampati sul terminale. Dato che anche i
messaggi di errore possono essere interessanti, si potrà effettuare la
redirezione anche per lo \textit{standard error} utilizzando l'operatore
``\texttt{2>}'', così per salvare gli errori di un comando si dovrà usare
qualcosa del tipo:
\begin{Example}
comando 2> errori.txt
\end{Example}
si tenga presente inoltre che la sintassi dell'uso del numero di file
descriptor prima dell'operatore funziona anche per gli altri operatori di
redirezione, questo ad esempio significa che si potrà anche effettuare la
redirezione in \textit{append} dello \textit{standard error} utilizzando come
operatore ``\texttt{2>\hspace{0.0001mm}>}''.

Se poi si vuole eseguire la redirezione sia dello \textit{standard output} che
\textit{standard error} basterà redirigerli entrambi. Fintanto che si
utilizzano due file diversi basterà semplicemente utilizzare gli operatori
visti finora specificati in un ordine qualsiasi, si presenta però un problema
qualora si volesse effettuare la redirezione di entrambi sullo stesso file,
perché usando due redirezioni distinte questo verrebbe scritto attraverso due
file descriptor indipendenti.\footnote{il risultato porterebbe a delle
  sovrascritture, la problematica è piuttosto sottile e se ne possono
  afferrare tutte le conseguenze solo con una conoscenza dettagliata delle
  modalità con cui vengono gestiti file e file descriptor in un sistema
  unix-like, l'argomento va al di là di quanto sia possibile affrontare in
  questo testo, chi fosse interessato può consultare il capitolo 5 di
  \cite{GaPiL}.} Per questo motivo viene fornito un operatore diverso,
``\texttt{\&>}'', che permette di effettuare questa operazione, così se si
vogliono scrivere sia i risultati che gli errori di un comando sullo stesso
file si potrà usare qualcosa del tipo:
\begin{Example}
comando &> output.txt
\end{Example}
esistono comunque altre sintassi equivalenti per effettuare la stessa
operazione, riportate in tab.~\ref{tab:shell_redirection}.

\itindbeg{pipelining} 

La redirezione di ingresso ed uscita, per quanto utile, è però di gran lunga
meno significativa rispetto ad una terza forma di redirezione, detta
\textit{pipelining}, che viene realizzata tramite l'operatore ``\verb/|/''. È
questa funzionalità infatti quella che permette di eseguire quella
concatenazione dei comandi a cui abbiamo accennato in
sez.~\ref{sec:shell_design}.

L'operatore ``\verb/|/'' consente di collegare lo \textit{standard output} del
comando che lo precede con lo \textit{standard input} del comando che lo
segue.  Questo viene fatto utilizzando una ``\textit{pipe}'', un servizio di
comunicazione fra processi fornito dal kernel che, come indica il nome stesso,
costituisce una sorta di \textsl{conduttura} di collegamento fra i due
comandi.

Una \textit{pipe} è del tutto analoga alle \textit{fifo} incontrate in
sez.~\ref{sec:struct_file_vfs}, quello che un processo scrive su un capo,
viene letto da un altro processo sull'altro capo, solo che una \textit{pipe}
non è associata ad un oggetto sul filesystem, ma esiste solo come file
descriptor accessibile dall'interno dei processi interessati.  Se questi file
descriptor sono rispettivamente lo \textit{standard output} di un primo
comando e lo \textit{standard input} del secondo si otterrà il collegamento
voluto e sarà possibile fornire come dati in ingresso ad un comando quelli
prodotti in uscita da un altro.

Si possono così lanciare in sequenza una serie di comandi in cui ciascuno
elabora i risultati del precedente, effettuando combinazioni ed elaborazioni
anche molto complesse.  Come esempio proviamo a contare in quanti file di
testo è suddiviso il contenuto di questo testo, se ricordiamo che l'opzione
\texttt{-n} del comando \texttt{cat} consente di numerare le righe di un file,
potremo ottenere una lista numerata con:
\begin{Console}
piccardi@ellington:~/truedoc/corso$ \textbf{ls *.tex | cat -n}
     1	advadmin.tex
     2	appendici.tex
     3	config.tex
     4	corso.tex
     5	netadmin.tex
     6	netbase.tex
     7	netdns.tex
     8	netinter.tex
     9	netlpi.tex
    10	ordadmin.tex
    11	ringraziamenti.tex
    12	shell.tex
    13	stradmin.tex
    14	struttura.tex
\end{Console}
%$
mandando la lista dei file generata da \texttt{ls} in ingresso a \texttt{cat}.

La disponibilità di questa funzionalità comincia a farci intuire quali possono
essere le capacità intrinseche della riga di comando. Ad esempio non è più
necessario dover inserire in tutti i comandi una opzione per ordinare in una
qualche maniera i risultati prodotti in uscita, basterà inviare questi ultimi
con una \textit{pipe} al programma \texttt{sort}, il cui solo scopo è quello
di effettuare riordinamenti nelle modalità più varie.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Comando} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{cmd < file}  & redirige lo \textit{standard input}: legge l'input
                           del comando \texttt{cmd} dal file \texttt{file}.\\ 
    \texttt{cmd > file}  & redirige lo \textit{standard output}: scrive il
                           risultato del comando \texttt{cmd} sul file
                           \texttt{file}.\\ 
    \verb|cmd >> file|   & redirige lo \textit{standard output}: scrive il
                           risultato del comando \texttt{cmd} accodandolo al
                           contenuto del file \texttt{file}.\\ 
    \texttt{cmd 2> file} & redirige lo \textit{standard error}: scrive gli
                           errori del comando \texttt{cmd} sul file 
                           \texttt{file}.\\ 
    \texttt{cmd1 | cmd2} & \textit{pipelining}: redirige
                           lo \textit{standard output} del comando
                           \texttt{cmd1} sullo \textit{standard input}
                           del comando \texttt{cmd2}.\\   
    \texttt{cmd > file 2>\&1} & redirige lo \textit{standard output} e lo 
                                \textit{standard error}: scrive errori e
                                risultati del comando \texttt{cmd} sul file
                                \texttt{file}.\\ 
    \texttt{cmd >\& file}     & stesso effetto del precedente.\\ 
    \texttt{cmd \&> file}     & stesso effetto del precedente.\\ 
    \texttt{cmd1 2>\&1 | cmd2}& redirige lo \textit{standard output} e lo 
                                \textit{standard error} del comando
                                \texttt{cmd1} sullo \textit{standard input}
                                del comando \texttt{cmd2}.\\ 
    % \texttt{cmd <> file}      & apre il file descriptor 0 in lettura e
    %                             scrittura sul file \texttt{file}.\\
    \hline
  \end{tabular}
  \caption{Principali modalità di redirezione.}
  \label{tab:shell_redirection}
\end{table}

Vedremo in sez.~\ref{sec:shell_fileutils} molti altri esempi di come il
\textit{pipelining} può essere sfruttato per costruire delle vere e proprie
\textsl{catene di montaggio} in cui si ottiene un risultato finale attraverso
la concatenazione di molti comandi, concludiamo questa sezione riportando in
tab.~\ref{tab:shell_redirection} un riassunto delle principali modalità di
redirezione utilizzate nella shell, comprese alcune delle più esoteriche che
permettono di redirigere più file; per una trattazione completa si consulti la
pagina di manuale, alla sezione ``\texttt{REDIRECTION}''.

\itindend{pipelining} 
\itindend{standard~input}
\itindend{standard~output}
\itindend{standard~error}

\subsection{Scripting elementare}
\label{sec:shell_scripting}

Una delle capacità fondamentali della shell è che si possono inserire, come
avveniva per i file \texttt{.bat} del DOS, delle sequenze di comandi in un
file per farli eseguire direttamente senza doverli riscrivere tutte le volte.
Ma se questo è più o meno tutto quello che si può fare con il DOS, il grande
vantaggio di una shell Unix è che si ha a disposizione un vero e proprio
linguaggio di programmazione con tanto di variabili e direttive di iterazione,
condizionali, ecc. che permette di effettuare anche compiti di notevole
complessità. E nonostante che come linguaggio di programmazione sia poco
elegante e piuttosto limitato, lo \textit{shell scripting} viene comunque
utilizzato ampiamente, data la sua immediatezza, per automatizzare una gran
quantità di operazioni per le quali non vale la pena ricorrere ad un
linguaggio di più alto livello.

È per questo motivo che la shell, anche se finora ne abbiamo parlato solo come
del programma che implementa l'interfaccia a riga di comando, è in realtà uno
dei componenti essenziali per far funzionare il sistema, si noti infatti che,
come richiesto dal \textit{Filesystem Hierarchy Standard} trattato in
sez.~\ref{sec:file_FHS}, essa deve trovarsi sotto \texttt{/bin}, dato che è
essenziale per l'avvio del sistema.  Questo perché non è necessaria solo dal
punto di vista dell'interfaccia utente: anche i meccanismi di avvio del
sistema infatti, come vedremo in sez.~\ref{sec:struct_sysv_init}, usano
proprio degli \textsl{script di shell} per eseguire le loro operazioni.

La descrizione dettagliata della shell come linguaggio di programmazione va al
di là dello scopo di questo testo, le sue caratteristiche principali si
trovano comunque nella sezione ``\texttt{SHELL GRAMMAR}'' della pagina di
manuale, ed un ottima risorsa per quanti vogliano approfondirlo è
\cite{AdvBash}.  Quello che è importante sottolineare qui è che la shell non
solo può essere invocata in maniera interattiva, quando è associata ad un
terminale ed utilizzata dagli utenti per dare comandi, ma può anche essere
lanciata non interattivamente facendole eseguire direttamente quello che
appunto si chiama uno \textit{script}. In questo caso la si invoca come un
qualunque altro comando, e prende come argomento il file dello script da
eseguire, con una sintassi del tipo \texttt{bash script}.

\itindbeg{link-loader}

In realtà gli script possono sfruttare una funzionalità peculiare del
cosiddetto \textit{link-loader} di Linux (che vedremo anche in
sez.~\ref{sec:cfg_dyn_lib}) comune a tutti i sistemi unix-like, che oltre ad
eseguire i programmi nel formato binario standard è in grado di eseguire anche
gli script, che vengono trattati esattamente allo stesso modo.  Questi sono
identificati dal \textit{link-loader} come file di testo dotati di permesso di
esecuzione la cui prima riga è nella forma:
\begin{Example}
#!/bin/bash
\end{Example}
in cui cioè si trovano i caratteri ``\verb|#!|'' seguiti dal pathname di un
programma che faccia da interprete.  In tal caso il \textit{link-loader}
lancerà automaticamente il programma interprete (con le opzioni che si possono
specificare sempre sulla prima riga del file) dandogli come argomento il nome
file stesso, così che questo esegua le istruzioni in esso contenute.

Dato che per la shell e per tutti i linguaggi di scripting che usano questa
funzionalità, come il Python o il Perl, il carattere ``\texttt{\#}'' indica
l'inizio di una riga di commento, quando si vuole creare uno script basterà
scrivere un file di testo contenente tutte le istruzioni necessarie che inizi
con questa riga, che verrà ignorata nell'interpretazione dei comandi, e poi
renderlo eseguibile.

Si tratta cioè di attivarne il permesso di esecuzione con \texttt{chmod +x}
anche se poi dal punto di vista del contenuto del file non cambierà
assolutamente nulla, restando questo un normale file di testo. Ma in questa
maniera uno script sarà del tutto equivalente ad un comando binario, ed oltre
ad eseguirlo come tale la shell provvederà anche a passargli gli argomenti
scritti sulla riga di comando, esattamente come avrebbe fatto se si fosse
trattato di un eseguibile compilato.

\itindend{link-loader}

Oltre alla sintassi di base illustrata in sez.~\ref{sec:shell_sintax}, che
resta sempre disponibile, quando si scrivono degli script di shell si fa
spesso ricorso a istruzioni e costrutti sintattici il cui uso è poco comune
sulla riga di comando, sia perché essi sono attinenti a funzionalità più
complesse che sono poco indicate per un uso interattivo, sia perché dipendono
da funzionalità direttamente legate all'uso all'interno degli script.

Una sintassi poco utilizzata nell'uso interattivo è quella che permette di
eseguire più comandi sulla stessa linea; cosa che può essere fatta in tre
modalità diverse.  La prima modalità prevede che i singoli comandi siano
separati fra di loro tramite il carattere ``\texttt{;}''. In tal caso si
tratta semplicemente di scrivere su una riga unica quello che altrimenti si
scriverebbe su linee diverse, usando il ``\texttt{;}'' per separare la fine di
un comando dall'inizio del successivo. In questo caso i vari comandi saranno
eseguiti in sequenza da sinistra a destra come se al posto del ``\texttt{;}''
si fosse premuto invio.

Questa sintassi è di scarsa utilità sulla linea di comando, se non per
eseguire più comandi in sequenza, senza dover stare ad attendere che ciascuno
di essi finisca per poter scrivere il successivo. Ha però una sua utilità
specifica negli script dove alcune direttive di programmazione, come i
condizionali che vedremo a breve, usano come parametro una linea di comando,
la cui terminazione può essere resa esplicita con questo metodo.

Una seconda modalità di esecuzione multipla è quella in cui i comandi che si
vogliono eseguire vengono separati dall'operatore ``\texttt{\&\&}'', che
assume il significato di AND logico. In questo caso il comando successivo
all'operatore verrà eseguito soltanto se il precedente non ha avuto errori
mentre in caso di errori la catena verrà immediatamente interrotta. Questo
operatore consente di eseguire un secondo comando solo se il primo ha avuto
successo e l'uso di questa sintassi è comune negli script ad esempio per
verificare se un certo file esiste e in caso affermativo eseguire un comando.

Una terza modalità di esecuzione multipla prevede che i diversi comandi sulla
stessa linea vengano separati dall'operatore ``\verb/||/'', che assume il
significato di OR logico. In questo caso si avrà che il comando successivo
all'operatore verrà eseguito soltanto se il precedente ha fallito.  Questo
consente di eseguire in alternativa due comandi; in genere lo si usa negli
script per eseguire le operazioni da effettuare solo in caso di errori.

Queste due ultime modalità fanno riferimento, per stabilire se un comando ha
avuto o meno successo, a quella caratteristica comune di tutti i programmi che
una volta terminati riportano al programma che li ha lanciati (nel caso
specifico la shell) uno stato di uscita che serve ad indicare se le operazioni
sono state concluse correttamente.  Abbiamo già accennato a questa
funzionalità in sez.~\ref{sec:struct_proc_property}, quando abbiamo trattato
degli \textit{zombie} che derivano dal non ricevere correttamente questo stato
di uscita. La shell è ovviamente programmata per riceverlo correttamente, e ne
utilizza il valore proprio per determinare se il programma è finito
correttamente o meno.

La convenzione utilizzata universalmente è che un valore nullo (cioè 0)
significa il successo delle operazioni, mentre un valore non nullo (in genere
1) indica che c'è stato un errore. Inoltre se il programma non si è concluso
spontaneamente ma è stato interrotto da un segnale la shell assegna al codice
di uscita il valore di $128+n$, dove $n$ è il numero del segnale (ed
ovviamente il comando viene considerato fallito).

Tutte le volte che un programma viene eseguito la shell riceve questa
informazione, ed è con un controllo automatico su questi valori che, nell'uso
degli operatori ``\texttt{\&\&}'' e ``\verb/||/'', vengono prese le decisioni
sull'esecuzione o meno dei vari comandi che la shell concatena tramite essi.

La presenza di un codice di uscita è molto importante, specie per gli script,
che possono usare questa informazione per capire se ci sono stati problemi
nell'esecuzione di un comando.  Per questo la shell, nel ricevere lo stato di
uscita di un comando, lo memorizza nella variabile speciale ``\texttt{?}''. In
questo modo nella riga di comando successiva o in uno script diventa possibile
controllare lo stato di uscita dell'ultimo comando eseguito facendo
riferimento ad essa con ``\texttt{\$?}''.

Si deve inoltre precisare che tutte le volte che si concatenano più comandi,
sia con gli operatori condizionali appena visti, che con una \textit{pipe},
che con l'uso del ``\texttt{;}'', alla fine dell'esecuzione della intera riga
di comando nella variabile ``\texttt{?}'' verrà riportato il codice di uscita
dell'ultimo programma eseguito.  

Vediamo allora un esempio di come utilizzare questa funzionalità, potremo
verificare che in un caso in cui il comando viene eseguito senza errori si
ottiene:
\begin{Console}
piccardi@anarres:~/truedoc$ \textbf{ls}
Makefile       adminbook.tex  images                 macro.aux     sicurezza
README         commons        introduzione_sviluppo  mailservices  webservices
...
piccardi@anarres:~/truedoc$ \textbf{echo $?}
0
\end{Console}
mentre qualora si abbia un errore si ottiene:
\begin{Console}
piccardi@anarres:~/truedoc$ \textbf{ls licidi}
ls: cannot access licidi: No such file or directory
piccardi@anarres:~/truedoc$ \textbf{echo $?}
1
\end{Console}
quindi nel primo caso, in cui il comando è stato eseguito correttamente, il
valore della variabile ``\texttt{?}'' è 0, mentre nel secondo, in cui
\texttt{licidi} non esiste, si ha un errore ed il valore è 1.

La variabile ``\texttt{?}'' è una delle \index{variabili!speciali}
\textsl{variabili speciali} della shell descritte nella sezione
``\texttt{Special Parameters}'' della pagina di manuale. Queste variabili
vengono mantenute direttamente dalla shell stessa (non ha cioè senso
assegnarle direttamente come visto in sez.~\ref{sec:shell_sintax}) che vi
memorizza il valore di alcuni parametri interni. L'elenco delle principali
\textsl{variabili speciali} è riportato in tab.~\ref{tab:shell_special_var}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Variabile} & \textbf{Contenuto} \\
    \hline
    \hline
     \texttt{\#}& il numero degli argomenti passati ad uno script.\\
     \texttt{*} & la lista degli argomenti. Se espansa fra virgolette come
                  \verb|"$*"| è equivalente ad una unica stringa formata dal %$
                  contenuto dei singoli argomenti separato da spazi (o dal
                  carattere di separazione specificato in \texttt{IFS}).\\
     \verb|@|   & la lista degli argomenti. Se espansa fra virgolette come
                  \verb|"$@"| è equivalente alla lista dei singoli argomenti.\\
     \texttt{?} & il codice di uscita dell'ultimo comando eseguito.\\
     \texttt{\$}& il PID della shell.\\
     \texttt{!} & il PID del programma in \textit{background} che è stato
                  eseguito per ultimo.\\
     \texttt{0} & il nome della shell o dello script.\\
     \texttt{-} & la lista delle opzioni con cui è stata invocata  o che sono
                  attive per la shell corrente.\\
    \hline
  \end{tabular}
  \caption{Le principali \textsl{variabili speciali} della shell.}
  \label{tab:shell_special_var}
\end{table}

Alcune di queste \textsl{variabili speciali} sono ad uso specifico degli
script; ad esempio quando si lancia uno script con degli argomenti con
\texttt{\$\#} si ottiene il numero degli stessi, con \texttt{\$1} il primo
argomento, con \texttt{\$2} il secondo, ecc. È inoltre possibile ottenere una
stringa contenente tutti gli argomenti con \texttt{\$*}, mentre con
\texttt{\$@} si ottiene una lista.

La differenza fra \texttt{\$*} e \texttt{\$@} può sembrare non significativa,
e se si stampano le due variabili con \texttt{echo} non se ne vedrà nessuna.
In realtà questa è fondamentale negli script, infatti \texttt{\$*} nelle
istruzioni usate negli script viene considerata come un'unica stringa, mentre
\texttt{\$@} viene espansa in una lista, costituita da tanti elementi quanti
sono gli argomenti passati allo stesso. Questo comporta ad esempio che nel
caso si usi la prima in una istruzione \texttt{for} si avrà un solo ciclo,
mentre con la seconda si avranno tanti cicli quanti sono gli argomenti.

Per capire meglio come si usano facciamo un esempio, consideriamo allora il
seguente script:
\begin{FileExample}[label=prova.sh]
#! /bin/sh
echo "Questo script ha $# argomenti"
echo "Argomento n.1 $1, n.2 $2, ecc."
echo "l'insieme degli argomenti: $@"  
\end{FileExample}
in cui si utilizzano le variabili speciali relative al numero di argomenti, al
primo ed al secondo argomento ed alla lista completa; se lo si esegue
passandogli tre argomenti si otterrà come risultato:
\begin{Console}
piccardi@ellington:~$ \textbf{./prova.sh arg1 arg2 arg3}
Questo script ha 3 argomenti
Argomento n.1 arg1, n.2 arg2, ecc.
l'insieme degli argomenti: arg1 arg2 arg3  
\end{Console}
%$

Oltre a ricevere degli argomenti sulla riga di comando, uno script di shell
può anche, come i normali programmi, leggere dati dallo \textit{standard
  input} ed interagire anche in questo modo con l'utente. Il comando più usato
per ottenere dati in questo modo è \index{comando!built-in!\texttt{read}}
\texttt{read}, che legge una riga dallo \textit{standard input} e la divide in
parole che assegna come valore alle variabili che si sono specificate come
argomento.

In questo caso di nuovo viene usata la variabile \texttt{IFS} per suddividere
in parole la riga. Si tenga presente che il comando legge una riga alla volta,
per cui se dobbiamo specificarne più di una occorrerà rieseguire il comando o
fare un ciclo. Inoltre il comando esegue l'assegnazione delle singole parole
alle singole variabili fintanto che queste sono nello stesso numero. Se si
sono indicate più variabili che parole, alle variabili eccedenti sarà
assegnato un valore nullo, viceversa se ci sono più parole che variabili
all'ultima variabile sarà assegnata la parte di riga restante.

Oltre alla possibilità di passare argomenti, e di leggere dati dallo
\textit{standard input}, un'altra delle caratteristiche che rendono uno script
di shell qualcosa di molto più sofisticato di una semplice sequenza di righe
di comando, ed affine un programma vero e proprio, è il supporto per una serie
di \textsl{istruzioni} che consentono di creare costrutti sintattici
complessi, propri di un linguaggio di programmazione.  Di questi illustreremo
solo i più significativi, come accennato l'elenco completo è nella sezione
``\texttt{SHELL GRAMMAR}'' della pagina di manuale.

Abbiamo visto come i due operatori ``\texttt{\&\&}'' e ``\verb/||/''
consentano di effettuare un'esecuzione condizionata di un comando a seconda
dello stato di uscita del precedente. La shell consente però anche una
costruzione più esplicita e completa delle esecuzioni condizionali, basandosi
sull'uso dell'istruzione \index{shell!istruzione!\texttt{if}} \texttt{if}, la
cui forma generica è:
\begin{Example}
if condition_cmd;  then 
   command
   ...
else 
   command
   ...
fi
\end{Example}

In questo caso in genere non si usa una singola riga di comando in quanto la
sintassi richiesta prevede l'uso di più istruzioni, combinate opportunamente.
In particolare l'esempio precedente ci mostra come dopo l'\texttt{if} iniziale
si debba scrivere il comando il cui stato di uscita viene a costituire la
condizione da controllare, seguito dall'istruzione \texttt{then}. Si noti
anche come nell'esempio si sia indicata esplicitamente la fine del comando con
il carattere ``\texttt{;}'' senza il quale sarebbe stato necessario scrivere
l'istruzione \texttt{then} su una riga a parte.

Il comando soggetto dell'istruzione \texttt{if} viene sempre eseguito ed a
seconda del suo risultato verranno eseguiti la lista di comandi inseriti dopo
l'istruzione \index{shell!istruzione!\texttt{then}} \texttt{then} se questo ha
successo (cioè riporta un valore di uscita nullo) o quelli scritti dopo
l'istruzione \index{shell!istruzione!\texttt{else}} \texttt{else} se questo
fallisce (cioè riporta un valore di uscita non nullo).  Il blocco condizionale
deve comunque essere sempre terminato esplicitamente con l'istruzione
\index{shell!istruzione!\texttt{fi}} \texttt{fi}. L'uso di \texttt{else} è
opzionale, se non ci sono alternative si possono specificare solo i comandi da
eseguire se il comando ha successo fra \texttt{then} e \texttt{fi}.

La precedente sintassi può essere resa ancora più complessa in quanto è
possibile realizzare blocchi condizionali annidati sostituendo l'istruzione
\texttt{else} con l'istruzione \index{shell!istruzione!\texttt{elif}}
\texttt{elif}. L'istruzione è sostanzialmente identica ad \texttt{if}, e
consente di eseguire come alternativa, al posto dei comandi posti dopo
l'istruzione \texttt{else}, un ulteriore blocco condizionale, con la stessa
sintassi appena illustrata, introdotto dall'\texttt{elif} invece che da un
\texttt{if}.

Oltre all'esecuzione condizionata di blocchi di istruzioni, la shell permette
di eseguire cicli condizionali tramite l'uso delle due istruzioni
\index{shell!istruzione!\texttt{while}} \texttt{while} e
\index{shell!istruzione!\texttt{until}} \texttt{until}. Entrambe le istruzioni
permettono la ripetizione di un insieme di comandi sulla base del risultato di
un altro comando (specificato come argomento) che serve ad esprimere la
condizione.  La lista dei comandi da eseguire nel ciclo deve essere delimitata
dalle istruzioni \index{shell!istruzione!\texttt{do}} \texttt{do} e
\index{shell!istruzione!\texttt{done}} \texttt{done}.

Il comando che esprime la condizione viene sempre valutato all'inizio del
ciclo; le successive istruzioni vengono eseguite se ha successo nel caso di
\texttt{while} o se fallisce nel caso di \texttt{until}. Se il ciclo
condizionale viene eseguito, alla sua conclusione la condizione viene
rivalutata con la riesecuzione del comando iniziale, ed il ciclo eventualmente
ripetuto a seconda del nuovo risultato ottenuto. Un esempio della sintassi per
\texttt{while} è il seguente:
\begin{Example}
while condition_cmd; do
    command
    ...
done
\end{Example}
e la sintassi è identica nel caso si usi \texttt{until}.

Se si devono operare scelte diverse sulla base del valore di una variabile si
può usare l'istruzione \index{shell!istruzione!\texttt{case}} \texttt{case}.
In generale \texttt{case} prende come argomento una espressione che possa
assumere valori diversi. Il caso più comune è quello di una variabile da
referenziare con la \textit{variable expansion}, ma si può utilizzare anche il
risultato di una \textit{command expansion}.  L'istruzione permette di
eseguire comandi diversi a seconda dei valori che l'espressione di controllo
può assumere, con una sintassi generica del tipo di:
\begin{Example}
case expression in 
    value1) 
        command
        ...
    ;;
    value2)
        command
        ...
    ;;
    *)
        command
        ...
    ;;
esac
\end{Example}
in cui ogni caso viene terminato da un doppio ``\texttt{;;}'' ed i singoli
valori con cui viene confrontata l'espressione sono terminati da una parentesi
chiusa. Si può esprimere il valore generico con un ``\texttt{*}''. La lista
dei casi deve sempre essere terminata con l'istruzione
\index{shell!istruzione!\texttt{esac}} \texttt{esac}.

L'utilità di \texttt{case} rispetto all'uso di una serie concatenata di
\texttt{if} ed \texttt{elif}, oltre alla leggibilità, è che i valori con cui
effettuare il controllo supportano i caratteri jolly con lo stesso significato
che questi assumono nel \textit{filename globbing} visto in
sez.~\ref{sec:shell_sintax}, anche se in questo caso vengono applicati alla
lista dei valori forniti dall'espressione piuttosto che ai nomi dei file, (è
per questo che si può usare ``\texttt{*}'' per indicare il valore
generico). Questa funzionalità consente di raggruppare in maniera flessibile
valori simili e trattarli con una unica serie di istruzioni.

Infine l'istruzione \index{shell!istruzione!\texttt{for}} \texttt{for}
permette di compiere dei cicli su un numero stabilito di alternative,
definendo al contempo una variabile che può essere utilizzata all'interno del
ciclo, con una sintassi del tipo:
\begin{Example}
for var in list ; do
   command
   ...
done
\end{Example}
dove di nuovo le istruzioni \texttt{do} e \texttt{done} delimitano le
istruzioni compiute all'interno del ciclo mentre \texttt{var} è la variabile
che assume, per ciascuna ripetizione del ciclo, i vari possibili valori
risultanti dall'espansione dell'espressione \texttt{list}.

Il comando interpreta semplicemente il valore di \texttt{list} come una lista
costituita di valori singoli separati da spazi, assegnando in sequenza i
singoli valori a \texttt{var} per ciascuna ripetizione del ciclo. La potenza
del comando risiede nel fatto che per esprimere \texttt{list}, oltre ad una
eventuale elencazione esplicita dei valori, si può utilizzare sia la
\textit{variable expansion}, che la \textit{command expansion} che il
\textit{filename globbing}.

Come complemento alla possibilità di eseguire ciclicamente un gruppo di
comandi con istruzioni come \texttt{for}, \texttt{while} ed \texttt{until},
sono state previste due istruzioni che permettono di controllare il flusso di
esecuzione all'interno di un ciclo. La prima istruzione è
\index{shell!istruzione!\texttt{continue}} \texttt{continue}, che conclude
immediatamente il ciclo corrente per passare immediatamente al successivo,
saltando tutte le istruzioni restanti. La seconda è
\index{shell!istruzione!\texttt{break}} \texttt{break}, che termina
immediatamente la ripetizione del ciclo e passa alla prima istruzione ad esso
seguente. 

Siccome è possibile annidare più cicli uno dentro l'altro, entrambe le
istruzioni supportano un argomento numerico che indica di quanti livelli
tornare indietro, il valore deve essere un intero maggiore di uno, e se si
specifica un livello superiore al numero di annidamenti si tornerà
semplicemente al più esterno dei cicli presenti.

Una delle caratteristiche comuni a tutti i linguaggi di programmazione, e la
shell non fa eccezione, è quella della possibilità di definire delle funzioni
da richiamare per eseguire direttamente in diverse occasioni la stessa serie
di istruzioni. Questa capacità ha una conseguenza sulla sintassi della shell,
perché quando si scrive un comando questo può fare riferimento, oltre ad
eventuali programmi o script o ad un alias per un altro comando, ad una
funzione, che viene appunto eseguita scrivendone il nome.

Benché sia possibile farlo anche sulla riga di comando, in generale una
funzione è definita all'interno di uno script, e viene introdotta dalla parola
chiave \index{shell!istruzione!\texttt{function}} \texttt{function} cui segue
il nome della funzione e il costrutto ``\texttt{()}''. In realtà l'istruzione
\texttt{function} è opzionale e può essere omessa, perché per la definizione
di una funzione è sufficiente la presenza di un nome seguito dal costrutto
``\texttt{()}'', quest'ultimo a sua volta può essere omesso se si usa
l'istruzione \texttt{function}.

Dopo di che il corpo della funzione, che contiene tutte le istruzioni da essa
eseguite, deve essere scritto di seguito delimitato fra parentesi graffe. In
sostanza la forma di una funzione di shell è sempre qualcosa del tipo:
\begin{Example}
function name () { 
   command 
   ...
}
\end{Example}
dove ciascuna linea conterrà un comando o altre istruzioni, esattamente come
si potrebbero mettere in uno script; a differenza di uno script però queste
verranno eseguite nella shell corrente e non in un processo a parte.

\index{shell!subshell|(}

L'uso degli script ci pone di fronte anche alcune conseguenze non immediate
del funzionamento dell'architettura dei processi. Come accennato infatti
quando si lancia uno script di shell esso viene eseguito come un comando: la
shell crea un nuovo processo figlio in cui esegue quella che si chiama una
\textit{subshell}, cioè un'altra istanza di se stessa che interpreta lo
script. Tutto questo ha delle precise conseguenze: ad esempio se in uno script
si effettuano modifiche alle variabili di ambiente o agli \textit{alias}
queste saranno effettive solo per la relativa \textit{subshell}, e non per la
shell originaria che l'ha lanciato, non essendo possibile ad un processo
modificare le proprietà di un altro processo.

Per questo motivo, se si vogliono automatizzare una serie di impostazioni per
la shell corrente, ad esempio impostare alcune variabili di ambiente, non si
può pensare di farlo con uno script eseguito in una \textit{subshell} che
contenga i relativi comandi.  È però possibile far eseguire direttamente alla
shell corrente i comandi scritti in un file, senza usare una
\textit{subshell}, ottenendo così le impostazioni volute.

Per fare questo è disponibile il comando interno
\index{comando!built-in!\texttt{source}} \texttt{source} che richiede il nome
del file da cui leggere le istruzioni come argomento. Una sintassi
alternativa, che però è quella che è stata standardizzata da POSIX.2 e si
trova pertanto su tutte le shell compatibili, è quella che prevede l'uso di
``\texttt{.}''  al posto di \texttt{source}. In questo caso non è necessario
che il file contenente i comandi sia eseguibile e presenti la sintassi di uno
script con il ``\texttt{\#!}'' iniziale, dato che il suo contenuto viene
semplicemente letto ed eseguito dalla shell come se lo si fosse scritto
direttamente sul terminale.

La \texttt{bash} inoltre è in grado di distinguere questa condizione ed
accorgersi se viene eseguita o meno in una \textit{subshell} tramite il valore
della variabile predefinita \texttt{SHLVL} che indica il cosiddetto
``\textsl{livello}''. Questo valore parte da 1 per le shell lanciate
direttamente da un altro programma, come quella ottenuta all'avvio o al lancio
di un terminale virtuale, e viene incrementato di uno ogni volta che una shell
viene lanciata da un'altra shell. In questo modo è possibile capire se si è
all'interno di una \textit{subshell} o meno ed eventualmente tenerne conto
all'interno degli script.

Un comando interno complementare a \texttt{source} è
\index{comando!built-in!\texttt{exec}} \texttt{exec} che consente di eseguire
un altro programma al posto della shell corrente. In questo caso quello che
succede è che il processo resta lo stesso (e ad esempio non cambia il suo
PID), ma viene messo in esecuzione al suo interno il codice del programma
passato come argomento ad \texttt{exec}. Questo programma può anche essere uno
script, ma si deve tenere presente che in tal caso, pur restando il processo
lo stesso, il programma messo in esecuzione sarà la \textit{subshell} che
interpreta lo script, che verrà eseguita al posto della shell corrente,
sostituendola completamente. Questo significa che a differenza di quanto
avviene con l'uso di \texttt{source} si può lanciare con \texttt{exec} solo
uno script eseguibile e non un semplice file, e che alla terminazione dello
script si avrà anche la terminazione del processo, senza poter tornare nella
shell da cui si era partiti.

\index{shell!subshell|)}

Infatti con \texttt{exec} la conclusione del programma che si è fatto eseguire
fa terminare anche il processo da cui si è partiti, e se questo era la shell
con cui ci si è collegati al sistema, si ottiene anche la conclusione della
sessione di lavoro. Per questo in genere questa istruzione viene utilizzata
all'interno degli script quando questi devono porre in esecuzione al proprio
posto altri programmi.

Oltre alle istruzioni interne della shell esistono anche una serie di comandi
di utilità che sono stati creati proprio per facilitare la scrittura di
script. Il primo di questi è \index{comando!\texttt{seq}} \texttt{seq}, che
permette di stampare sullo \textit{standard output} una sequenza di numeri.

Il comando può essere invocato con un numero di argomenti variabile da uno a
tre numeri interi: un solo argomento indica il numero finale a cui fermare la
sequenza, partendo da 1 ed incrementando di uno, specificando due argomenti si
indicano il valore iniziale ed il valore finale, che viene raggiunto sempre a
passi di uno. Infine se si forniscono tre argomenti il secondo argomento viene
usato come valore di incremento nell'intervallo che inizia con il primo e
finisce col terzo.  Questo comando è molto utile quando si vogliono fare dei
cicli, lo si può infatti usare per generare una lista di numeri da utilizzare
con l'istruzione \texttt{for}, i cui valori possono poi essere utilizzati
all'interno del ciclo; ad esempio per eseguire dieci volte la stessa serie di
comandi si potrà usare qualcosa del tipo:
\begin{Example}
for i in `seq 1 10`; do
   command
   ...
done
\end{Example}

Altri due comandi speciali sono \index{comando!\texttt{true}} \texttt{true} e
\index{comando!\texttt{false}} \texttt{false}, che non fanno assolutamente
nulla se non fornire alla shell un valore di ritorno. Nel caso di
\texttt{true} si avrà un valore nullo, corrispondente ad una esecuzione sempre
corretta, che nelle istruzioni condizionali implica vero. Se invece si usa
\texttt{false} questo restituisce un valore non nullo, cioè un fallimento del
comando, equivalente alla condizione falsa.  Questi due programmi vengono
usati spesso come shell di default (vedi sez.~\ref{sec:cfg_user_db}) per gli
account degli utenti di sistema che non devono avere una shell effettiva.

Un altro comando utilizzato negli script per il suo codice di uscita è
\index{comando!\texttt{test}} \texttt{test} che è uno dei comandi più comuni
utilizzato come argomento per le istruzioni condizionali illustrate in
precedenza, e che nel caso di \texttt{bash} è presente anche come comando
interno.  Dato che il comando serve ad eseguire dei controlli su cui esprimere
una condizione, una modalità alternativa per invocarlo è con il nome
``\texttt{[}'' (si può infatti osservare l'esistenza del file
\texttt{/usr/bin/[}) nel qual caso la linea di comando che lo utilizza dovrà
essere terminata con una corrispondente ``\texttt{]}''.

È questo il motivo per cui le condizioni che si trovano spesso negli script di
shell richiedono che dopo la parentesi quadra sia sempre presente uno spazio:
non si tratta infatti di una sintassi interna della shell attivata da un
carattere di controllo, ma di un comando vero e proprio, che come tale deve
essere riconosciuto con le regole classiche dei nomi dei comandi, che sono
separati da spazi dai relativi argomenti.

Il comando può eseguire controlli su un gran numero di condizioni diverse,
passate come argomenti in forma di una opportuna espressione, ritornando un
valore nullo se la condizione è verificata, e non nullo altrimenti. Il comando
inoltre supporta l'uso di alcuni \textsl{operatori}, come ``\texttt{!}'', che
anteposto ad una espressione ne nega il risultato, e la combinazione logica di
due espressioni con l'uso delle opzioni \texttt{-a} e \texttt{-o}, che
indicano rispettivamente l'AND e l'OR. In questo modo si possono costruire
delle condizioni molto complesse.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-b \textsl{file}} & il file esiste ed è un dispositivo a blocchi.\\
    \texttt{-c \textsl{file}} & il file esiste ed è un dispositivo a caratteri.\\
    \texttt{-d \textsl{file}} & il file esiste ed è una directory.\\
    \texttt{-e \textsl{file}} & il file esiste.\\
    \texttt{-f \textsl{file}} & il file esiste ed è un file normale.\\
    \texttt{-h \textsl{file}} & il file esiste ed è un link simbolico.\\
    \texttt{-O \textsl{file}} & il file esiste ed è di proprietà
                                dell'\textit{effective user ID} del processo.\\
    \texttt{-G \textsl{file}} & il file esiste ed è proprietà
                                dell'\textit{effective group ID} del processo.\\
    \texttt{-r \textsl{file}} & il file esiste ed è leggibile.\\
    \texttt{-s \textsl{file}} & il file esiste ed ha dimensione maggiore di
                                zero.\\ 
    \texttt{-w \textsl{file}} & il file esiste ed è scrivibile.\\
    \texttt{-x \textsl{file}} & il file esiste ed è eseguibile.\\
    \hline
  \end{tabular}
  \caption{Opzioni per le condizioni sui file del comando \texttt{test}.}
  \label{tab:cmd_test_file_options}
\end{table}

Buona parte delle condizioni verificate da \texttt{test} fanno riferimento
alle proprietà dei file, in questo caso la condizione viene espressa con una
opzione seguita dal nome del file cui la si vuole applicare. Le principali
opzioni utilizzate, ed il relativo significato, sono riportati in
tab.~\ref{tab:cmd_test_file_options}.

Oltre alle condizioni sui singoli file il comando può essere usato per
esprimere condizioni relative a due file, in tal caso queste vengono espresse
scrivendo questi ultimi come argomenti separati dalla relativa opzione. Con
\texttt{-ef} si richiede che essi abbiano lo stesso \textit{inode}, con
\texttt{-nt} si richiede che il primo sia più recente (in termini di tempo di
ultima modifica, vedi sez.~\ref{sec:struct_file_vfs}) mentre con \texttt{-ot}
che sia più vecchio (negli stessi termini).

Una ultima serie di condizioni riguarda l'uso di stringhe e numeri; per questi
ultimi valgono gli operatori di confronto dei valori come \texttt{-eq},
\texttt{-ge}, \texttt{-gt}, \texttt{-le}, \texttt{-lt} e \texttt{-ne}, il cui
significato è banale (uguale, maggiore uguale, maggiore, minore uguale,
minore, e diverso). Per le stringhe invece si possono usare gli operatori
``\texttt{=}'' e ``\texttt{!=}'' per indicare rispettivamente uguaglianza e
disuguaglianza, mentre l'opzione \texttt{-z} serve a verificare se la stringa
è vuota e l'opzione \texttt{-n} se non lo è.

% TODO trattare read e l'uso degli here statement (<<EOF ecc.)



\subsection{Le modalità operative e la configurazione della shell}
\label{sec:shell_operation_modes}

L'esempio degli script rende evidente come, benché il programma sia lo stesso,
la shell possa essere utilizzata in modi diversi. In generale una shell usata
per eseguire uno script necessiterà di impostazioni diverse rispetto ad una
shell usata per gestire la riga di comando (ad esempio non serve il
\textit{prompt}).  Per poter effettuare delle impostazioni diverse a seconda
del tipo di utilizzo la \texttt{bash} supporta modalità di funzionamento che
vengono abilitate a seconda di come essa viene lanciata, si ricordi infatti
che la shell è un programma come gli altri e la si può eseguire direttamente
sulla riga di comando esattamente come gli altri, ottenendo appunto una
\textit{subshell}.

\index{shell!di~login|(}

In particolare quando ci si collega ad una macchina attraverso la shell, che
sia su una \textit{console}, con un emulatore di terminale o tramite una
connessione via rete, devono essere eseguite una serie di inizializzazioni,
come la definizione del prompt e della variabile \texttt{PATH}, che
normalmente non servono nel caso di uno script, che eredita le impostazioni
dalla shell corrente. Per questo esiste una apposita modalità di invocazione
che consente di ottenere quella che viene chiamata una \textsl{shell di
  login}, che può essere attivata esplicitamente dall'uso dell'opzione
\texttt{-l}.

In realtà i vari programmi che lanciano una \textsl{shell di login} (come
\texttt{login} per l'accesso da \textit{console}) invece di usare l'opzione
\texttt{-l}, lo fanno apponendo un ``\texttt{-}'' come primo carattere
dell'argomento zero (quello che indica il nome del programma) fra quelli
passati alla shell posta in esecuzione, il che poi ci permette di identificare
le shell di login nell'output di \texttt{ps}, come si può vedere anche
nell'esempio di pag.~\pageref{sec:process_ps_out}. Dato che la \texttt{bash}
analizza gli argomenti, compreso questo, se riconosce di essere stata lanciata
come \texttt{-bash} provvederà a comportarsi come \textsl{shell di login}.

Quello che contraddistingue una shell di login è che al suo avvio vengono
sempre eseguite una serie di procedure di inizializzazione specifiche.  La
prima di queste è l'esecuzione all'interno della shell stessa, come se si
fosse usato il comando \texttt{source}, di tutte le istruzioni contenute nel
file \index{configurazione!\texttt{/etc/profile}} \texttt{/etc/profile}, in
cui l'amministratore di sistema può inserire una serie di impostazioni comuni
per tutti gli utenti. Questa è una caratteristica generale che hanno tutte le
shell derivate dalla Bourne shell, e non solo la \texttt{bash},\footnote{per
  chi fosse interessato quelle derivate dalla C shell usano invece
  \texttt{/etc/csh.login}.} pertanto occorre, come nell'esempio, tenerlo
presente ed utilizzare funzionalità specifiche della \texttt{bash} solo in
maniera condizionale.

Un esempio di questo file, che può essere considerato una sorta di file di
configurazione della shell, è riportato di seguito. L'esempio è preso dalla
versione installata di default su una Debian Squeeze, e la sua lettura può
essere considerata anche un buon esercizio per prendere familiarità con alcune
delle istruzioni che abbiamo illustrato in sez.~\ref{sec:shell_scripting}:
\begin{FileExample}[label=/etc/profile]
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).

if [ "`id -u`" -eq 0 ]; then
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
  PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
fi
export PATH

if [ "$PS1" ]; then
  if [ "$BASH" ]; then
    # The file bash.bashrc already sets the default PS1.
    # PS1='\h:\w\$ '
    if [ -f /etc/bash.bashrc ]; then
      . /etc/bash.bashrc
    fi
  else
    if [ "`id -u`" -eq 0 ]; then
      PS1='# '
    else
      PS1='$ '
    fi
  fi
fi

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi
\end{FileExample}
%$

Come si può notare nel file si usano dei condizionali per effettuare delle
impostazioni, ed in particolare in un paio di occasioni si usa una
\textit{command expansion} per controllare il risultato del comando
\texttt{id} (vedi sez.~\ref{sec:user_sys_info}) che consente di ottenere
l'\textit{user ID} dell'utente e decidere quali configurazioni applicare a
seconda che questi sia o meno l'amministratore.  Si può notare allora come
prima venga impostata la variabile \texttt{PATH} a seconda del tipo di utente,
e poi il prompt con \texttt{PS1}, se questa non risulta già definita.

Si noti come anche in questo caso se la shell usata è la \texttt{bash}, nel
qual caso sarebbe definita la variabile
\index{variabili!di~shell!\texttt{BASH}} \texttt{BASH}, l'impostazione del
prompt viene demandata all'uso di \texttt{/etc/bash.bashrc} (su cui torneremo
a breve) che assegna a \texttt{PS1} un valore analogo a quello commentato, che
sfrutta le funzionalità illustrate in tab.~\ref{tab:shell_prompt_command}.
Invece per una shell standard minimale, come potrebbe essere la \texttt{dash}
usata da Debian per gli script di avvio, non essendo garantite le funzionalità
in più della \texttt{bash} vengono usati direttamente i caratteri
``\texttt{\#}'' e ``\texttt{\$}'' a seconda che l'utente sia o meno
l'amministratore.

Infine vengono trattate ulteriori eventuali personalizzazioni, da inserire in
singoli file sotto \texttt{/etc/profile.d/} il cui nome deve terminare in
\texttt{.sh}. Per questo viene usato un ciclo di \texttt{for} sui nomi
ottenuti con il \textit{filename globbing}, controllando che i file siano
leggibili, e nel caso ne vengono eseguite le istruzioni. In questa versione
del file non viene più impostato il valore della \textit{umask} (vedi
sez.~\ref{sec:struct_file_perm_comm}) per la sessione come avveniva in
precedenza, cosa che è demandata ad uno specifico modulo di PAM (tratteremo
l'argomento in sez.~\ref{sec:cfg_user_PAM}).

Per permettere agli utenti di aggiungere le loro personalizzazioni alla shell
di login, dopo aver letto \texttt{/etc/profile} per eseguire le impostazioni
comuni a tutto il sistema, la \texttt{bash} cerca nella home dell'utente, ed
in quest'ordine, i file \index{configurazione!\texttt{.bash\_profile}}
\texttt{.bash\_profile}, \index{configurazione!\texttt{.bash\_login}}
\texttt{.bash\_login} e \index{configurazione!\texttt{.profile}}
\texttt{.profile}, ed esegue i comandi del primo che trova, senza guardare gli
altri. Si noti come nessuno di questi file sia eseguibile, dato che non viene
eseguito come script, per cui è sufficiente il permesso di lettura.  Un
esempio di \texttt{.profile} (sempre ripreso da una Debian Squeeze) è il
seguente:
\begin{FileExample}[label=.profile]
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
	. "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
\end{FileExample}
dove sostanzialmente se la shell è la \texttt{bash}, riconosciuta stavolta per
la presenza della variabile di default \texttt{BASH\_VERSION} si utilizzano
eventuali impostazioni personali poste nel file \texttt{.bashrc} (su cui
torneremo a breve) e si aggiunge al \texttt{PATH}, se questa esiste, la
directory \texttt{bin} nella home dell'utente.

Infine all'uscita di una shell di login è prevista l'esecuzione, se questo
esiste, delle istruzioni contenute nel file
\index{configurazione!\texttt{.bash\_logout}} \texttt{.bash\_logout}, che può
essere utilizzato per effettuare eventuali operazioni di ripulitura alla
conclusione di una sessione di lavoro, un esempio di questo file è il
seguente, sempre ripreso da una Debian Squeeze:
\begin{FileExample}[label=.bash\_logout]
# ~/.bash_logout: executed by bash(1) when login shell exits.

# when leaving the console clear the screen to increase privacy

if [ "$SHLVL" = 1 ]; then
    [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q
fi
\end{FileExample}
%$
in cui viene controllata la variabile \texttt{SHLVL} che indica il
\textsl{livello} della shell per eseguire, se non si è in una
\textit{subshell}, le operazioni di ripulitura della console perché su questa
non restino tracce della sessione precedente.

\index{shell!di~login|)}
\index{shell!interattiva|(}
 
L'uso dei file \texttt{/etc/bash.bashrc} e \texttt{.bashrc} visto negli esempi
precedenti, ci porta ad un'altra delle modalità di utilizzo della shell,
quella in cui essa opera su linea di comando associata ad un terminale, ma
senza essere un shell di login, come avviene ad
esempio per le shell lanciate dagli emulatori di terminale messi in esecuzione
all'interno dell'interfaccia grafica.  In questo caso si ha quella che si
chiama \textsl{shell interattiva}.  La shell viene
eseguita in modalità interattiva se invocata senza argomenti e con
\textit{standard output} e \textit{standard input} associati ad un terminale,
o se lanciata esplicitamente come tale con l'opzione \texttt{-i}.  In tal caso
viene automaticamente definita la variabile \texttt{PS1} e nella variabile
speciale \texttt{\$-} (vedi tab.~\ref{tab:shell_special_var}) comparirà la
lettera ``\texttt{i}''.

Se la shell è interattiva e non di login cambia semplicemente la modalità di
inizializzazione; le impostazioni generali per tutti gli utenti vengono lette
da \index{configurazione!\texttt{/etc/bash.bashrc}} \texttt{/etc/bash.bashrc}
invece che da \texttt{/etc/profile}, mentre le impostazioni personali vengono
lette direttamente da \index{configurazione!\texttt{.bashrc}} \texttt{.bashrc}
invece che da uno dei tre file \texttt{.bash\_profile}, \texttt{.bash\_login}
e \texttt{.profile}. Un esempio di \texttt{.bashrc}, ripreso dalla versione
installata da Debian Squeeze per l'amministratore, è il seguente:
\begin{FileExample}[label=.bashrc]
# ~/.bashrc: executed by bash(1) for non-login shells.

# Note: PS1 and umask are already set in /etc/profile. You should not
# need this unless you want different defaults for root.
# PS1='${debian_chroot:+($debian_chroot)}\h:\w\$ '
# umask 022

# You may uncomment the following lines if you want `ls' to be colorized:
# export LS_OPTIONS='--color=auto'
# eval "`dircolors`"
# alias ls='ls $LS_OPTIONS'
# alias ll='ls $LS_OPTIONS -l'
# alias l='ls $LS_OPTIONS -lA'
#
# Some more alias to avoid making mistakes:
# alias rm='rm -i'
# alias cp='cp -i'
# alias mv='mv -i'
\end{FileExample}
% $
e come si può notare riguarda principalmente la possibilità, scommentando le
relative linee, di definire degli alias ed un prompt specifico.  Dato che una
shell di login è anche interattiva, si capisce la precedente scelta per cui
tutte le impostazioni comuni, sono demandate ai file \texttt{/etc/bash.bashrc}
e \texttt{.bashrc} che vengono poi utilizzati direttamente da
\texttt{/etc/profile} e da \texttt{.profile}.

\index{shell!interattiva|)}

Come si può notare le differenze fra queste diverse modalità di invocazione
sono minime, e attinenti per lo più a come viene eseguita la procedura di
inizializzazione di ambiente e variabili di shell. Tale procedura non è più
necessaria (e pertanto non viene eseguita) tutte le volte che si riesegue la
shell come \textit{subshell} per lanciare uno script all'interno di una shell
interattiva o di login.

Una terza modalità di funzionamento della \texttt{bash} si attiva quando
questa viene invocata con il nome di \texttt{sh}, in tal caso infatti essa
cercherà di simulare la caratteristiche di funzionamento di una shell POSIX
elementare, per mantenere al massimo la compatibilità, e molte delle
funzionalità avanzate non saranno disponibili. In questo caso ad esempio se la
shell viene eseguita come shell di login, per le impostazioni saranno presi in
considerazione solo \texttt{/etc/profile} e \texttt{.profile}.

\index{shell!ristretta|(} 

Infine oltre alle modalità appena illustrate, \texttt{bash} supporta un'ultima
modalità speciale, che si attiva invocandola con l'opzione \texttt{-r} o
chiamandola direttamente come \texttt{rbash}: quella della cosiddetta
\textit{modalità ristretta}.\footnote{benché nel manuale della \texttt{bash}
  si parli anche in questo caso di \textit{restricted shell}, la cosa non è da
  confondere con l'omonimo concetto illustrato in sez.~\ref{sec:cfg_login} che
  attiene ad una shell generica.} Invocando la shell in questa maniera è
possibile creare un ambiente ``\textsl{ristretto}'' in cui essa è soggetta ad
una serie di limitazioni che consentono di circoscrivere e controllare il suo
funzionamento, un elenco delle limitazioni più importanti attive con questa
modalità è il seguente:
\begin{itemize*}
\item non sarà possibile cambiare directory con il comando \texttt{cd}.
\item non si potranno modificare o cancellare le variabili di shell
  \texttt{SHELL}, \texttt{PATH}, \texttt{ENV}, o \texttt{BASH\_ENV}.
\item non si potranno specificare nomi di comandi contenenti il carattere
  ``\texttt{/}''.
\item saranno bloccate le redirezioni dell'output.
\item non si potrà usare il comando interno \texttt{exec} per eseguire un
  altro programma al posto della shell.
\end{itemize*}
l'elenco completo, insieme ad una descrizione dettagliata di questa modalità
di funzionamento (che può essere utile per la limitazione di eventuali account
remoti) si può trovare nella sezione ``\texttt{RESTRICTED SHELL}'' della
pagina di manuale.

\index{shell!ristretta|)} 


Ma al di là di queste modalità generali, la \texttt{bash} consente di
controllare alcuni aspetti più specifici del proprio funzionamento attraverso
l'impostazione di alcune opzioni interne. Il comando principale che si usa per
questo è \index{comando!built-in!\texttt{set}} \texttt{set}, che abbiamo già
incontrato in sez.~\ref{sec:shell_sintax} per visualizzare le variabili e le
funzioni di shell definite quando viene usato senza specificare nessuna
opzione. In realtà il comando consente di effettuare diversi compiti: ad
esempio se invocato senza opzioni con una lista di argomenti riassegna gli
stessi alle variabili speciali \texttt{\$1}, \texttt{\$2}, ecc. consentendo
quindi di modificare la lista degli argomenti all'interno di uno script.

Ma lo scopo principale del comando è quello di controllare vari aspetti del
funzionamento della shell, modificando quelli che il manuale chiama gli
``\textsl{attributi}'' della stessa. Ciascuno di questi attributi è
identificato da una lettera e viene attivato specificando quest'ultima a modo
di opzione, preceduto dal carattere ``\texttt{-}'' mentre viene disattivato se
preceduto dal carattere ``\texttt{+}''.  Ad esempio abbiamo accennato in
sez.~\ref{sec:shell_IO_redirect} che se si esegue \texttt{set -C} la shell
riporterà un errore tutte le volte che si effettua una redirezione su un file
esistente, invece di sovrascriverlo.

Un secondo attributo importante si abilita con \texttt{set -e} che attiva
l'uscita immediata della shell qualora ci sia un errore in un comando. Si usa
questa modalità principalmente negli script (vedi
sez.~\ref{sec:shell_scripting}) per interromperne automaticamente l'esecuzione
in caso di errore, le uniche eccezioni sono quando gli errori avvengono in una
istruzione condizionale, comprese quelle espresse con ``\texttt{\&\&}'' e
``\texttt{||}''.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Attributo} & \textbf{Significato}\\
    \hline
    \hline
     \texttt{-a}& inserisce automaticamente nell'ambiente qualunque variabile
                  venga definita.\\ 
     \texttt{-f}& se attivata disabilita il \textit{filename globbing}.\\ 
     \texttt{-e}& se attivata fa sì che la shell esca immediatamente
                  in caso di errore nell'esecuzione di un
                  comando.\\ 
     \texttt{-u}& se attivata fa sì che la shell stampi un errore in
                  caso di riferimento ad una variabile non 
                  definita.\\ 
     \texttt{-C}& se attivata fa sì che la shell non sovrascriva un file
                  esistente in caso di redirezione (vedi
                  sez.~\ref{sec:shell_IO_redirect}) segnalando un errore.\\ 
    \hline
     \texttt{-o \textsl{opt}}& imposta l'opzione di funzionamento della shell
                  passata come parametro.\\  
    \hline
  \end{tabular}
  \caption{Principali attributi della shell, indicati come opzioni del comando
    interno \texttt{set}.} 
  \label{tab:shell_set_attribute}
\end{table}

I principali attributi che si possono impostare con \texttt{set} sono
riportati nella prima parte di tab.~\ref{tab:shell_set_attribute} in forma di
opzione, per l'elenco completo e la descrizione dettagliata del significato di
ciascuno di essi si può fare riferimento alla descrizione nella sezione
``\texttt{SHELL BUILTIN COMMANDS}'' della pagina di manuale. Nella seconda
parte si mantenuta separata l'opzione \texttt{-o}, perché essa costituisce una
sorta di estensione degli attributi precedenti e consente di attivare (o
disattivare se usata come \texttt{+o}) le cosiddette ``\textsl{opzioni}''
della shell, che attengono ad un insieme molto più ampio di modalità
operative. Queste devono essere indicate tramite un ulteriore parametro che
indica il nome dell'opzione; si sono indicate le più rilevanti in
tab.~\ref{tab:shell_set_options}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato}\\
    \hline
    \hline
    \texttt{allexport}& equivalente di \texttt{set -a}.\\ 
    \texttt{emacs}    & imposta l'editor di linea in stile \texttt{emacs} con
                        combinazioni da tastiera riprese dall'editor
                        \texttt{emacs} (il default di cui si è già parlato in
                        sez.~\ref{sec:shell_sintax}).\\ 
    \texttt{errexit}  & equivalente di \texttt{set -e}.\\ 
    \texttt{noclobber}& equivalente di \texttt{set -C}.\\ 
    \texttt{noglob}   & equivalente di \texttt{set -f}.\\ 
    \texttt{nounset}  & equivalente di \texttt{set -u}.\\ 
    \texttt{posix}    & cambia il comportamento della shell in modalità di
                        compatibilità con lo standard POSIX.2.\\ 
    \texttt{vi}       & imposta l'editor di linea in stile \texttt{vi}, in cui
                        le funzionalità di editing di linea usano combinazioni
                        da tastiera riprese dall'editor \texttt{vi} (vedi
                        sez.~\ref{sec:vi}.\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni della shell, da indicare come parametro
    dell'opzione \texttt{-o} di \texttt{set}.} 
  \label{tab:shell_set_options}
\end{table}

Come si può notare molte di queste opzioni ripropongono le impostazioni
modificabili direttamente con gli attributi di
tab.~\ref{tab:shell_set_attribute}, con alcune aggiunte, come la possibilità
di cambiare il comportamento delle combinazioni da tastiera per l'editor di
linea per adattarsi a quelle usate da alcuni editor molto diffusi. 



\section{I comandi dei file}
\label{sec:shell_fileutils}

Dato che in un sistema unix-like tutto è un file, è naturale che la maggior
parte dei comandi della ``\textit{unix toolbox}'' abbia a che fare con le
operazioni di manipolazione dei file. Abbiamo già visto in
sez.~\ref{sec:struct_files} i comandi elementari che ci permettono la gestione
dei file sul filesystem come \texttt{cp}, \texttt{mv}, \texttt{mkdir},
\texttt{ln}, \texttt{rm}, ecc. e quelli che consentono di operare sui
metadati, come \texttt{chown}, \texttt{chmod}, ecc.  In questa sezione
affronteremo gli altri comandi che permettono di operare sul contenuto dei
file ed eseguire su di essi operazioni più complesse; dato che buona parte di
queste vengono effettuate con la redirezione, vedremo anche delle applicazioni
di quest'ultima.


\subsection{Caratteristiche comuni}
\label{sec:cmd_general}

Benché, come anticipato in sez.~\ref{sec:shell_cli}, ogni comando sia
specializzato per fare un compito specifico, esistono comunque una serie di
caratteristiche comuni a tutti loro. Dato che i comandi relativi ai file sono
la maggioranza, le tratteremo qui, anche se si applicano in generale a
qualunque tipo di comando, e non solo a quelli che riguardano i file.  

La principale caratteristica comune a quasi tutti i comandi è la modalità di
gestione delle opzioni. Abbiamo illustrato nei dettagli in
sez.~\ref{sec:shell_sintax} come queste vengono elaborate dalla shell e
passate come argomenti al comando e come la gran parte dei comandi le elabori
attraverso una apposita libreria che ne assicura una sostanziale uniformità.
Quello che c'è da aggiungere qui è che alcune di esse, le più comuni, tendono
ad essere le stesse e ad avere lo stesso significato per tutti i comandi. Ad
esempio per la gran parte dei comandi l'opzione \texttt{-h} può essere
utilizzata per stampare a video una schermata di aiuto che riassume la
sintassi di uso del comando.

Ricordiamo comunque che quella di identificare come opzioni gli argomenti che
iniziano con il carattere ``\texttt{-}'' è solo una convenzione, e non è
seguita da tutti i comandi, alcuni infatti usano delle sintassi diverse per
eredità storiche, come abbiamo visto in sez.~\ref{sec:struct_proc_property}
con \texttt{ps}. La convenzione però viene usata estensivamente da tutti i
comandi di base realizzati all'interno del progetto GNU (quelli del pacchetto
\texttt{coreutils}) che hanno una certa uniformità anche nei nomi delle
opzioni, e da quelli che usano le funzionalità di gestione fornite della
libreria di sistema (la \textit{GNU C library}); per questo è molto diffusa.

Come accennato in sez.~\ref{sec:shell_sintax} le opzioni sono di due tipi: con
o senza parametri. Quando sono senza parametri esse si comportano come degli
interruttori che attivano o disattivano una certa modalità di funzionamento;
ad esempio l'opzione \texttt{-v} (che sta per \textit{verbose}) viene usata da
molti comandi per aumentare la \textsl{prolissità} dei propri messaggi. Le
opzioni che prevedono dei parametri sono più complesse e agiscono in maniera
analoga ad un cursore o una manopola; permettono cioè di passare dei valori di
controllo per una certa funzionalità del comando. In tal caso, con un formato
del parametro che varierà da caso a caso, il valore dovrà essere specificato
di seguito all'opzione, normalmente separato da uno spazio.

Inoltre, come accennato in sez.~\ref{sec:shell_sintax}, i comandi del progetto
GNU supportano anche una versione estesa delle opzioni, in cui queste si
possono specificare con parole intere invece che con singole lettere. In
questo caso esse iniziano sempre con un ``\texttt{-{}-}''. Tutti i comandi di
base del progetto GNU ad esempio supportano le due opzioni \texttt{-{}-help},
che stampa una schermata riassuntiva della sintassi (equivalente a
\texttt{-h}), e \texttt{-{}-version}, che stampa il numero di versione. Se
l'opzione estesa deve indicare un valore questo viene normalmente specificato
in forma di assegnazione con un ``\texttt{=}'', ad esempio con qualcosa del
tipo \texttt{-{}-tabsize=80}, anche se spesso basta fornire il valore separato
da uno spazio.

Si ricordi che l'interpretazione delle opzioni è un compito strettamente
attinente al singolo programma, per la shell un'opzione è una stringa come
un'altra che viene passata al comando che viene eseguito. Nasce allora il
problema di quando il valore di un certo argomento, come ad esempio il nome di
un file, inizia con il carattere ``\texttt{-}'', e non si ha modo di
distinguerlo da una opzione.  Dato che sulla linea di comando si possono
passare come argomenti anche i risultati delle varie espansioni (di comandi,
variabili o nomi di file), talvolta questo tipo di inconveniente può
verificarsi in maniera inaspettata.

Per questo motivo la combinazione ``\texttt{-{}-}'' usata da sola viene
utilizzata dalle librerie di gestione delle opzioni per forzare la conclusione
della scansione delle opzioni nella riga di comando, in modo che tutti gli
argomenti che seguono ad essa vengano usati dal programma letteralmente, senza
considerarli possibili opzioni, anche se cominciano per un ``\texttt{-}''.  Si
tenga presente però che questa è un'altra delle funzionalità introdotte dalla
funzione \texttt{getopt} della \textit{GNU C Library}, usata dalla gran parte
dei programmi, ma non da tutti, per gestire le opzioni a riga di comando.

Come esempio d'uso di questa funzionalità si consideri di dover cancellare con
\texttt{rm} un file il cui nome inizia per ``\texttt{-}'' (ad esempio
\texttt{-lista}).  Dato che il ``\texttt{-}'' con cui inizia il nome
normalmente viene interpretato come l'inizio di una opzione, l'uso di
\texttt{rm -lista} produce un errore essendo l'opzione \texttt{-l}
inesistente. Proteggere il ``\texttt{-}'' con la barra, o usare le virgolette
per il nome non serve a nulla, la shell interpreterà correttamente quanto
indicato, passando comunque il valore \texttt{-lista} come argomento. 

Il problema infatti non deriva dalla shell, ma da come vengono gestite le
opzioni nei comandi: tutti i programmi infatti prima esaminano le opzioni,
segnalando errori se ne trovano di inesistenti, e poi trattano gli
argomenti. Per questo occorre indicare esplicitamente al comando che in questo
caso non si vuole che il ``\texttt{-}'' sia interpretato come l'inizio di una
opzione: scrivendo il comando come \texttt{rm -{}- -lista}, l'interpretazione
delle opzioni viene bloccata dal ``\texttt{-{}-}'' e a questo punto
\texttt{-lista} (anche se inizia per ``\texttt{-}'') verrà considerato un
normale argomento che indica il nome di un file, che sarà cancellato.

Un'ultima convenzione, seguita anch'essa da molti programmi, riguarda l'uso
del singolo carattere ``\texttt{-}'' come argomento. La convenzione viene
utilizzata dai comandi che prendono come argomento un nome di file da cui
leggere o su cui scrivere dati. Se al posto del nome di un file si usa questo
carattere il comando farà riferimento rispettivamente allo \textit{standard
  input} per la lettura o allo \textit{standard output} per la scrittura.



\subsection{I comandi per le ricerche dei file}
\label{sec:cmd_search}

La ricerca di uno specifico file all'interno del filesystem, o dei file con
una certa serie di caratteristiche, è una operazione molto comune, e per
questo sono stati sviluppati alcuni comandi molto flessibili, che permettono
di effettuare le più complesse tipologie di ricerca.

Un primo comando che si può usare per cercare dei file l'abbiamo già
incontrato in sez.~\ref{sec:shell_sintax}, ed è \texttt{which}, che ci indica
a quale file eseguibile corrisponde un certo comando, facendo una ricerca
nelle directory indicate nel \textit{PATH}.  Una estensione di \texttt{which},
è il comando \index{comando!\texttt{whereis}} \texttt{whereis} che consente di
estendere la ricerca e ricercare oltre ai binari eseguibili anche le pagine di
manuale ed eventuali sorgenti associati ad un comando.

Il comando \texttt{whereis} prende come argomento il nome del file o comando
da cercare, e stampa i risultati sullo \textit{standard output}.  Si possono
restringere le ricerche soltanto a binari, pagine di manuale o sorgenti
utilizzando rispettivamente le opzioni \texttt{-b}, \texttt{-m} e
\texttt{-s}. Il comando prende il nome passato come argomento, elimina
eventuali estensioni (ad esempio se si cerca un sorgente elimina il
\texttt{.c}) ed esegue la ricerca in una serie di directory standard (elencate
nella pagina di manuale). Si possono restringere le ricerche a delle directory
specifiche per binari, pagine di manuale e sorgenti usando rispettivamente le
opzioni \texttt{-B}, \texttt{-M} e \texttt{-S} seguite dalle directory a cui
restringere la ricerca. Per tutti i dettagli e l'elenco completo delle opzioni
si consulti al solito la pagina di manuale.

Il comando più veloce per cercare un file in maniera generica sul filesystem è
\index{comando!\texttt{locate}} \texttt{locate}, che, come suggerisce il nome,
serve a localizzare sul filesystem tutti i file che contengono nel loro
pathname la stringa passata come argomento.  Il vantaggio di questo programma
è la sua velocità, esso infatti non effettua la ricerca con una scansione del
contenuto del disco, ma su un piccolo database interno che contiene l'elenco
di tutti i file presenti nel sistema. Di questo programma esistono diverse
versioni che si sono succedute nel tempo, qui prenderemo in considerazione
quella che viene fornita dal pacchetto \texttt{mlocate}, adottata da tutte le
principali distribuzioni.

Il comando riconosce l'opzione \texttt{-i}, che richiede che venga effettuata
una ricerca \textit{case insensitive}, e \texttt{-e} che richiede che sia
verificata l'effettiva esistenza del file. Il comando inoltre consente l'uso
come argomento di espressioni analoghe a quelle usate dalla shell per il
\textit{filename globbing} viste in sez.~\ref{sec:shell_sintax}, se si usa
l'opzione \texttt{-r} si potrà usare, come unico argomento, una espressione
regolare (vedi sez.~\ref{sec:cmd_regular_expression}).  Le altre opzioni e la
descrizione completa del comando è al solito disponibile nella relativa pagina
di manuale, accessibile con \texttt{man locate}.

Il fatto che \texttt{locate} si affidi ad un database ci fa capire
immediatamente anche i suoi limiti: anzitutto la ricerca può essere effettuata
solo per nome, ed inoltre il comando sarà in grado di effettuare la ricerca
solo sui file già inseriti nel database. Questo viene creato ed aggiornato
tramite il comando \index{comando!\texttt{updatedb}} \texttt{updatedb} che in
genere viene eseguito una volta al giorno (fra i lavori periodici di
\texttt{cron} che vedremo in sez.~\ref{sec:crontab}), per cui se un file è
stato creato dopo l'ultimo aggiornamento non si potrà vederlo.

Il comando \texttt{updatedb} prende una serie di opzioni in forma estesa, le
principali delle quali sono illustrate in tab.~\ref{tab:cfg_updatedb}, che gli
permettono di definire quale file usare per il database,\footnote{in genere
  (ad esempio per Debian e RedHat) viene usato
  \texttt{/var/lib/mlocate/mlocate.db}.}  quali directory (ad esempio non ha
molto senso indicizzare \texttt{/tmp}) e quali filesystem (non ha senso
indicizzare un CDROM o un filesystem di rete) inserire nel database dei file e
quali no.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-{}-output}    & indica il file su cui viene salvato il
                             database.\\  
    \hline
    \texttt{-{}-prunefs}   & indica l'elenco dei tipi di filesystem da non
                             indicizzare (il parametro deve essere passato
                             come lista separata da spazi dei rispettivi nomi,
                             come riportati in  
                             tab.~\ref{tab:file_filesystem_types}).\\
    \texttt{-{}-prunepaths}& indica la lista delle directory da non
                             indicizzare (il parametro deve essere passato
                             come lista separata da spazi dei rispettivi
                             pathname assoluti).\\
    \texttt{-{}-prunenames}& indica la lista di nomi di directory da non
                             indicizzare (il parametro deve essere passato
                             come lista separata da spazi) non sono consentiti
                             pathname assoluti né caratteri jolly.\\
    % \texttt{-{}-localuser} & indica l'utente locale per conto del quale
    %                          eseguire la ricerca sul filesystem nella
    %                          creazione del database.\\ %deprecata, locate
%    \texttt{-{}-netpaths}  & indica una lista di directory poste su filesystem
%                             di rete da inserire .\\ 
%    \texttt{-{}-} & .\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni di \texttt{updatedb}.}
  \label{tab:cfg_updatedb}
\end{table}

La caratteristica di \texttt{updatedb} è che i valori di alcune opzioni
(quelle riportate nella seconda parte di tab.~\ref{tab:cfg_updatedb}) possono
essere impostate attraverso l'uso del file di configurazione,
\index{configurazione!\texttt{/etc/updatedb.conf}}
\texttt{/etc/updatedb.conf}. Il file prevede che i valori siano assegnati in
forma di assegnazione di un valore ad una variabile di shell, con i nomi delle
variabili identici a quelli delle opzioni corrispondenti, ma scritte in
maiuscolo anziché minuscolo e senza il \texttt{-{}-} iniziale.  Un contenuto
tipico di questo file (così come ripreso dalla versione installata su una
Debian Squeeze) è il seguente:
\begin{FileExample}[label=/etc/updatedb.conf]
PRUNE_BIND_MOUNTS="yes"
# PRUNENAMES=".git .bzr .hg .svn"
PRUNEPATHS="/tmp /var/spool /media"
PRUNEFS="NFS nfs nfs4 rpc_pipefs afs binfmt_misc proc smbfs autofs iso9660 
 ncpfs coda devpts ftpfs devfs mfs shfs sysfs cifs lustre_lite tmpfs usbfs 
 udf fuse.glusterfs fuse.sshfs"
\end{FileExample}

% La motivazione di questa forma è che nella prima implementazione di questo
% comando effettivamente si trattava di usare delle variabili di ambiente, che
% venivano lette da questo file quando il comando veniva lanciato da uno degli
% script periodici eseguiti da \texttt{cron} (vedi sez.~\ref{sec:crontab}), e
% quello che veniva fatto era di definire queste variabili di ambiente
% all'interno di un file, \index{configurazione!\texttt{/etc/updatedb.conf}}
% \texttt{/etc/updatedb.conf}, che in questo modo faceva le veci di file di
% configurazione del comando.

Allora, in corrispondenza con le omonime opzioni di
tab.~\ref{tab:cfg_updatedb}, con \texttt{PRUNEFS} si indicano i filesystem da
non indicizzare, come quelli di rete, i filesystem virtuali come
\texttt{/proc} o quelli di dispositivi estraibili mentre con
\texttt{PRUNEPATHS} si indicano le directory da non indicizzare, come quelle
dei file temporanei, gli \textit{spool} delle code di stampa e della posta,
ecc. L'opzione \texttt{PRUNE\_BIND\_MOUNTS} è invece un valore logico, che
consente di eliminare le apparizioni duplicate degli stessi file che si
trovano al di sotto dei eventuali \textit{bind mount} (vedi
sez.~\ref{sec:file_disk_management}).

% e con
% \texttt{LOCALUSER} si indica l'utente con i permessi del quale sarà effettuata
% l'indicizzazione; nel caso si è usato \texttt{nobody},\footnote{questo è un
%   utente di servizio che non ha nessun privilegio nel filesystem, utilizzato
%   come titolare dei programmi che devono avere accesso solo alle informazioni
%   pubbliche.} in modo da evitare che siano indicizzati i file che gli utenti
% hanno protetto da lettura.

Un problema che si poneva con la prima versione di \texttt{locate} era che il
comando restituiva tutte le voci indicizzate indipendentemente dai loro
permessi, permettendo così ad un utente normale di verificare la presenza di
file per i quali non avrebbe accesso. Questo veniva risolto a livello di
indicizzazione eseguendo quest'ultima per conto di un utente senza privilegi
sul filesystem in modo da inserire nel database solo i file visibili
pubblicamente, con la conseguenza però che gli utenti non erano in grado di
avere indicizzati i propri file privati. Per risolvere questo problema le
versioni attuali del programma eseguono una indicizzazione generale e mostrano
i risultati verificando se i permessi dell'utente consentono l'accesso al
file.

% L'uso del comando è analogo a
% \texttt{locate} e supporta le opzioni citate in precedenza con lo stesso
% significato.  Il comando però utilizza un database con tutti i file, eseguendo
% la verifica dei permessi prima di mostrare i risultati. Per i dettagli sul suo
% funzionamento si può al solito consultare la pagina di manuale.\footnote{si
%   tenga presente che alcune distribuzioni, come Debian, installano
%   direttamente \texttt{slocate} come sostituto di \texttt{locate}, in tal caso
%   si potrà accedere al comando ed alla relativa documentazione continuando ad
%   usare il nome \texttt{locate}.}

% Dato che anche \texttt{slocate} necessita dell'uso di un database, insieme al
% programma viene fornito anche il relativo comando di indicizzazione
% \texttt{updatedb}. Il programma è un omonimo del precedente relativo a
% \texttt{locate},\footnote{su Debian quanto si installa \texttt{slocate} i
%   comandi \texttt{locate} e \texttt{updatedb} ordinari (e le relative pagine
%   di manuale) vengono rinominati in \texttt{locate.notslocate} e
%   \texttt{updatedb.notslocate}.} ed in realtà non è altro che un link allo
% stesso \texttt{slocate}, che quando viene invocato come \texttt{updatedb}
% abilita automaticamente l'opzione \texttt{-u} che forza la ricostruzione del
% database.\footnote{in questo caso il file usato di default è
%   \texttt{/var/lib/slocate/slocate.db}, ma può essere modificato con l'opzione
%   \texttt{-U}.}

% A differenza della versione associata a \texttt{locate}, l'\texttt{updatedb}
% di \texttt{slocate} esegue automaticamente una scansione di
% \texttt{/etc/updatedb.conf} (che costituisce quindi un vero file di
% configurazione per il comando), anche se riconosce solo un sottoinsieme delle
% variabili illustrate in precedenza, ed in particolare soltanto
% \texttt{PRUNEFS} e \texttt{PRUNEPATHS}, che assumono comunque lo stesso
% significato.

% Infine nelle distribuzioni più recenti il programma effettivamente
% utilizzato è \texttt{mlocate}, la cui sintassi e modalità di funzionamento è
% identica a quella di \texttt{slocate} (e prevede comunque i comandi
% \texttt{locate} e \texttt{updatedb}) ma deve il suo nome ad una maggiore
% efficienza di ricostruzione del database,\footnote{che nel caso è mantenuto
% in \texttt{/var/lib/mlocate/mlocate.db}.} dovuto al fatto che non sta a
% ricrearlo da zero tutte le volte ma effettua un operazione di
% \textsl{aggiunta} (la ``\texttt{m}'' sta per \textit{merging}) dei nuovi
% file).

Per superare i limiti di \texttt{locate} e affini, si può usare il comando
\index{comando!\texttt{find}} \texttt{find}, che non utilizza un database, ma
esegue la ricerca direttamente nel filesystem, al costo di una notevole
attività su disco, e di tempi di esecuzione decisamente più lunghi.  Si può
comunque ridurre il carico facendo effettuare la ricerca su sezioni ridotte
dell'albero dei file; il comando infatti prende come primo argomento la
directory da cui iniziare la ricerca, che verrà eseguita ricorsivamente in
tutte le directory sottostanti; se non si specifica nulla la ricerca partirà
dalla directory corrente.

Il comando supporta quattro categorie principali di opzioni, descritte da
altrettante sezioni della pagina di manuale, accessibile al solito con
\texttt{man find}. La prima categoria (descritta nella sezione
\texttt{OPTIONS}) contiene le opzioni vere e proprie, che controllano il
comportamento di \texttt{find}, la seconda, (descritta nella sezione
\texttt{TESTS}) contiene le opzioni di ricerca che permettono di selezionare i
file in base ad una loro qualunque proprietà (nome, tipo, proprietario, i vari
tempi, permessi, ecc.), la terza (descritta nella sezione \texttt{ACTIONS})
contiene le opzioni che permettono di specificare una azione da eseguire per
ciascun file che corrisponde alla ricerca, la quarta (descritta nella sezione
\texttt{OPERATORS}) contiene le opzioni che permettono di combinare fra loro
diverse selezioni.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{-L}         & dereferenzia i link simbolici, sostituisce la
                           precedente \texttt{-follow}, deprecata.\\
     \texttt{-mount}     & resta nel filesystem corrente e non analizza
                           sottodirectory in altri filesystem.\\
     \texttt{-maxdepth \textsl{n}}& limita la profondità della ricerca ad
                           \texttt{\textsl{n}} directory sotto quella di
                           partenza.\\ 
     \texttt{-mindepth \textsl{n}}& imposta la profondità iniziale della 
                           ricerca a \texttt{\textsl{n}} directory sotto
                           quella di partenza.\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni generiche di \texttt{find}.}
  \label{tab:cmd_find_generic_options}
\end{table}


Le opzioni generiche, le principali delle quali sono riportate in
tab.~\ref{tab:cmd_find_generic_options}, permettono di modificare il
comportamento del comando, ad esempio con \texttt{-maxdepth} si può limitare
la ricerca ai primi livelli di sottodirectory, mentre con \texttt{-mindepth}
la si può far partire da un certo sottolivello. Inoltre con \texttt{-L} si può
richiedere che il comando risolva eventuali link simbolici, facendo
riferimento ai file cui essi puntano anziché al link stesso, come avviene di
default.

Le maggiori potenzialità di \texttt{find} derivano dalla sua capacità di
effettuare ricerche con i criteri più svariati, da quelli sul nome del file in
varie forme (con \texttt{-name}, \texttt{-regex}, \texttt{-path}), a quelli
per gruppo e utente (con \texttt{-group} e \texttt{-user}), secondo i permessi
(con \texttt{-perm}), secondo i vari tempi (\texttt{-atime}, \texttt{-ctime},
\texttt{-mtime}) per tipo di file, di filesystem su cui è il file, ecc. Un
elenco delle principali opzioni di ricerca, con il relativo significato, è
riportato in tab.~\ref{tab:cmd_find_search_options}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{-amin \textsl{n}}& un file acceduto \texttt{\textsl{n}} minuti fa,
                                le opzioni \texttt{-cmin} e \texttt{-mmin} 
                                eseguono lo stesso controllo rispettivamente
                                con i tempi di ultimo cambiamento e ultima
                                modifica.\\ 
     \texttt{-atime \textsl{n}}&un file acceduto \texttt{\textsl{n}} giorni
                                fa, le opzioni \texttt{-ctime} e
                                \texttt{-mtime} eseguono lo stesso controllo
                                rispettivamente con i tempi di ultimo
                                cambiamento e ultima modifica.\\ 
     \texttt{-anewer \textsl{file}}& un file acceduto più recentemente di
                                \texttt{\textsl{file}}, le opzioni
                                \texttt{-cnewer} e \texttt{-mnewer} eseguono
                                lo stesso controllo rispettivamente con i
                                tempi di ultimo cambiamento e ultima
                                modifica.\\ 
     \texttt{-gid \textsl{n}} & il \textit{group ID} del gruppo proprietario è
                                \texttt{\textsl{n}}.\\ 
     \texttt{-group \textsl{group}}& il gruppo proprietario è
                                \texttt{\textsl{group}}.\\ 
     \texttt{-links \textsl{n}}&il file ha \texttt{\textsl{n}} 
                                 \textit{hard link}.\\
     \texttt{-name \textsl{pattern}}&il nome del file corrisponde al pattern
                                \texttt{\textsl{pattern}}. Prevede anche
                                \texttt{-iname} per una ricerca case
                                insensitive.\\ 
     \texttt{-path \textsl{pattern}}&il pathname del file (comprese quindi le
                                directory a partire dalla radice) corrisponde
                                al pattern \texttt{\textsl{pattern}}. Prevede
                                anche \texttt{-ipath} per una ricerca case
                                insensitive.\\
     \texttt{-perm \textsl{mode}}&i permessi corrispondono a
                                \texttt{\textsl{mode}}.\\ 
     \texttt{-size \textsl{n}}& la dimensione del file è \texttt{\textsl{n}}.\\
     \texttt{-type \textsl{c}}& seleziona sul tipo di file, il valore di
                                \texttt{\textsl{c}} corrisponde alla lettera
                                usata da \texttt{ls} e riportata in
                                tab.~\ref{tab:file_file_types}.\\
     \texttt{-uid \textsl{n}} & l'\textit{user ID} del proprietario è
                                \texttt{\textsl{n}}.\\ 
     \texttt{-user \textsl{user}}& il proprietario è \texttt{\textsl{user}}.\\
    \hline
  \end{tabular}
  \caption{Principali opzioni di \texttt{find} per la ricerca.}
  \label{tab:cmd_find_search_options}
\end{table}

Alcune di queste opzioni necessitano di alcuni chiarimenti, ad esempio con
l'opzione \texttt{-name} si può effettuare la classica ricerca sul nome del
file, con tanto di supporto per i caratteri jolly del \textit{filename
  globbing}, che però vanno adeguatamente protetti scrivendoli fra virgolette
per evitarne l'espansione da parte della shell.  La ricerca è effettuata
solamente sul nome del file così come è scritto nella directory che lo
contiene, e non sul suo pathname, se si vuole eseguire la ricerca su
quest'ultimo occorre usare \texttt{-path}.

Per tutte le opzioni che prendono un valore numerico che si è indicato in
tab.~\ref{tab:cmd_find_search_options} con ``\texttt{n}'', come quelle sui
tempi, gli identificatori, il numero di link, ecc. il comando permette una
sintassi molto potente: specificando solo il numero si richiede una
corrispondenza esatta, precedendolo con il segno ``\texttt{-}'' si richiede
invece che il valore sia inferiore, mentre precedendolo con un ``\texttt{+}''
si richiede che sia superiore. In questo modo ad esempio, nel caso dei tempi,
si può richiedere che un file sia più vecchio o più giovane di un dato tempo.
Per cui se si vogliono cercare i file modificati negli ultimi 5 minuti si
dovrà dare il comando:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{find . -mmin -5}
.
./shell.tex
\end{Console}
%$
mentre se si vuol cercare quelli non acceduti da più di quindici giorni si
farà:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{find . -atime +15}
./ringraziamenti.tex
\end{Console}
%$

L'opzione di ricerca sui permessi \texttt{-perm} merita una trattazione a
parte, il parametro \texttt{mode} passato all'opzione supporta infatti a sua
volta una sintassi abbastanza complessa. Anzitutto un permesso può essere
espresso sia in forma simbolica, con lo stesso formato visto in
sez.~\ref{sec:struct_file_perm_comm}, ma usando solo ``\texttt{=}'' come
operatore, che in forma numerica. Specificando un valore \texttt{find}
cercherà un file che abbia esattamente quel valore per i permessi, ad esempio
se si specifica \texttt{g=w} corrisponderanno soltanto i file con un permesso
numerico esattamente uguale a \texttt{020}.

Dato che in genere non si è interessati alla ricerca di un valore specifico di
tutti i permessi, quanto alla presenza di alcuni di essi, indipendentemente da
quali possono essere gli altri, il valore può essere specificato apponendovi,
in maniera simile a quanto si fa con i valori numerici, i due segni
``\texttt{-}'' e ``\texttt{+}'', in realtà quest'ultimo è ormai deprecato, ed
al suo posto occorre usare ``\texttt{/}''. Trattandosi però nel caso dei
permessi di una maschera di bit, il significato di questi caratteri non può
essere come in precedenza relativo ad un valore numerico maggiore o minore di
quello indicato, considerato poi che la notazione è valida anche per le
espressioni simboliche.

Dato che un valore espresso senza segno richiede la corrispondenza esatta, si
usano queste combinazioni per selezionare la presenza di uno o più bit senza
curarsi dello stato degli altri, che è in genere il tipo di ricerca più
utile. Se si usa il segno ``\texttt{-}'' allora \texttt{mode} dovrà
specificare, se si usa la forma simbolica, quali sono i permessi che devono
essere presenti sul file, oppure se si usa la maschera dei bit quali si vuole
che siano presenti (secondo lo schema di
fig.~\ref{fig:struct_bit_permission}), i bit nulli e gli altri permessi
verranno ignorati.  Se invece si usa ``\texttt{/}'' la richiesta è più debole
ed il file corrisponde purché almeno uno dei permessi specificati con il
valore di \texttt{mode} sia attivo. In questo modo con \texttt{-mode} si può
richiedere una condizione in cui siano attivi un permesso ``\textsl{e}'' un
altro, mentre con \texttt{/mode} una in cui siano attivi un permesso
``\textsl{o}'' un altro.

Come accennato una seconda importante categoria di opzioni è quella relativa
alle azioni; è possibile infatti, per ogni file che corrisponde al criterio di
ricerca specificato, far eseguire a \texttt{find} una certa azione. Se non si
specifica nulla l'azione di default è quella di stampare il nome del file,
equivalente alla opzione \texttt{-print}; ma si possono anche scrivere i nomi
su un file qualunque usando l'opzione \texttt{-fprint file}, o usare vari
formati di stampa.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{-exec}   & esegue un comando usando come argomento il nome del
                        file.\\ 
     \texttt{-print}  & stampa il nome del file terminato con un a capo.\\
     \texttt{-print0} & stampa il nome del file terminato con un carattere NUL
                        (il valore 0).\\
     \texttt{-fprint \textsl{file}}& scrive il nome del file sul file
                        \texttt{\textsl{file}}.\\ 
     \texttt{-ok}     & come \texttt{-exec} ma chiede conferma del comando.\\
    \hline
  \end{tabular}
  \caption{Principali opzioni di \texttt{find} per specificare azioni.}
  \label{tab:cmd_find_action_options}
\end{table}

L'elenco delle principali opzioni per le azioni è riportato in
tab.~\ref{tab:cmd_find_action_options}. Quella di gran lunga più importante è
\texttt{-exec} che permette di eseguire, per ogni file corrispondente alla
selezione, un comando. La sintassi dell'opzione è complessa in quanto si deve
inserire una riga di comando all'interno di un'altra, e ci sono delle
convenzioni usate dal comando per passare i valori.  Quando si usa
\texttt{-exec} tutto quello che segue viene interpretato come una riga di
comando fino a che non si incontra un carattere ``\texttt{;}'', in detta riga
si può fare riferimento al file che corrisponde con la stringa \texttt{\{\}}.
Il problema è che tutti questi caratteri vengono interpretati dalla shell, e
devono quindi essere adeguatamente protetti; allora se ad esempio si vogliono
spostare tutti i file non acceduti da più di 15 giorni in una directory
\texttt{old}, si potrà usare un comando del tipo:
\begin{Example}
find . -atime +15 -exec mv \{\} old \;
\end{Example}

La potenza del comando \texttt{find} è poi ulteriormente aumentata dal fatto
che le varie opzioni precedenti possono essere combinate fra di loro con degli
operatori logici. Ma se il significato di \texttt{-and} o \texttt{-or} può
sembrare immediato nel caso di criteri di ricerca, diventa meno chiaro quando
si ha a che fare con delle azioni. In realtà infatti il comando associa un
valore logico ad ogni opzione, e quando si esegue una selezione il valore è
automaticamente vero, lo stesso vale per tutte le azioni, tranne
\texttt{-exec} (e derivate come \texttt{-ok}) in cui il valore è vero se il
comando ha uno stato di uscita nullo, e falso altrimenti.

Il funzionamento di un operatore come \texttt{-and} (che è sottinteso se si
specificano più opzioni) è che la seconda opzione (sia questa di ricerca, che
una azione) viene eseguita solo se la prima è vera.  Viceversa con
\texttt{-or} la seconda opzione viene eseguita solo se la prima è falsa.
Infine \texttt{-not} nega il risultato di una opzione. 

Nel caso si combinino opzioni di ricerca tutto questo è del tutto ininfluente
riguardo il risultato del comando, che è quello che ci si aspetta
intuitivamente: entrambe le condizioni di ricerca devono essere soddisfatte
per \texttt{-and} o solo una per \texttt{-or}, o si inverte la selezione con
\texttt{-not}.  Le cose cambiano profondamente quando ci sono di mezzo delle
azioni come \texttt{-exec}, perché in tal caso l'esecuzione della seconda
opzione dipende dal risultato della prima: se si chiede di eseguire due
comandi ad esempio le cose dipendono dal risultato di quello che si esegue per
primo.

Per questo ad esempio specificare con \texttt{-and} più comandi (o
semplicemente scriverne più di uno, dato che in tal caso il \texttt{-and} è
sottinteso) non significa affatto che essi saranno eseguiti tutti: lo saranno
solo se tutti hanno successo, se uno non ha successo i successivi non saranno
eseguiti. Qualora si voglia essere sicuri di eseguire tutti i comandi in una
lista si può usare l'operatore ``\texttt{,}'' nel qual caso saranno eseguiti
comunque tutti, ma si avrà un valore finale corrispondente all'ultimo della
lista.


\subsection{I comandi per visualizzare il contenuto dei file}
\label{sec:cmd_file_visualisation}

Si sono raccolti in questa sezione tutti i comandi che permettono di
visualizzare il contenuto di un file. Il primo comando di questo tipo è
\texttt{cat}, che abbiamo già incontrato in
sez.~\ref{sec:shell_IO_redirect}. In tale occasione abbiamo anche accennato
come in realtà l'uso principale di questo comando (a parte il caso di file
molto corti) sia quello di permettere la concatenazione del contenuto di più
file, e che se lo scopo è solo quello della visualizzazione del contenuto di
un file esistono alternative migliori; adesso tratteremo proprio queste.

Il problema maggiore dell'uso di \texttt{cat} come visualizzatore è che questo
scrive tutto sul terminale, senza possibilità di mostrare il contenuto del
file un po' alla volta. Per questo sono stati allora creati tutta una serie di
programmi studiati per mostrare il contenuto dei file una \textsl{pagina} alla
volta (dove per pagina si intende la schermata del terminale), che per questo
sono detti \itindex{pager} \textit{pager}.  Ad essi è dedicata anche una
variabile di ambiente, \index{variabili!di~ambiente!\texttt{PAGER}}
\texttt{PAGER}, usata dai programmi che necessitano di visualizzare il
contenuto di un file, per scegliere quale fra i vari comandi di
visualizzazione deve essere utilizzato.

Il primo programma realizzato per la visualizzazione di interi file è
\index{comando!\texttt{more}} \texttt{more}, il quale prende come argomento
una lista di file da leggere di cui stampa il contenuto sul terminale una
pagina alla volta, attendendo che l'utente invii dei comandi da tastiera.  Al
solito la pagina di manuale riporta l'elenco completo delle opzioni ed i vari
comandi usati per controllare il comportamento del programma. Ad esempio con
\texttt{-num} si può specificare un parametro che indica il numero di linee
che devono essere stampate sullo schermo (utile solo quando il comando non
riesce a determinarlo da solo).  Rimandiamo ad essa per le informazioni
complete, qui faremo solo una breve panoramica sui principali comandi che si
possono dare durante la visualizzazione, il cui elenco comunque può essere
ottenuto direttamente durante l'uso del programma premendo i tasti
``\texttt{?}'' o ``\texttt{h}''.

Una volta stampata una pagina \texttt{more} consente di passare a quella
successiva con la pressione dello spazio, mentre l'uso del ritorno a capo
permette di avanzare lo scorrimento di una riga alla volta. Si può
interrompere la visualizzazione con ``\texttt{q}'', mentre con ``\texttt{b}''
si può tornare una pagina indietro. Se si sono indicati più file con
\texttt{:n} si può passare alla visualizzazione del successivo mentre con
\texttt{:p} tornare al precedente. Con il tasto ``\texttt{/}'' si fa apparire
un prompt dove inserire una stringa da ricercare all'interno del file. In
realtà la stringa viene interpretata come una \textsl{espressione regolare}
(vedi sez.~\ref{sec:cmd_regular_expression}), quindi si possono effettuare
anche ricerche molto complesse. Infine con ``\texttt{v}'' si può lanciare
l'editor impostato con la variabile di ambiente \texttt{EDITOR} per modificare
il contenuto del file (gli editor sono trattati in sez.~\ref{sec:editor},
quello usato di default è \texttt{vi}).

Il comando \texttt{more} è stato creato fin dagli albori di Unix, e la sua
sintassi risente anche del fatto che i primi terminali erano delle
telescriventi, su cui il testo veniva stampato, per cui non supporta ad
esempio l'uso dei tasti di freccia avanti e indietro ed i vari tasti di
spostamento presenti nelle tastiere moderne. Dato che ben presto tutti i
terminali iniziarono a supportare la riscrittura dello schermo, e tutte le
tastiere iniziarono ad avere i tasti di spostamento, venne creato
\index{comando!\texttt{less}} \texttt{less} come
\textsl{evoluzione}\footnote{si, volevano davvero fare gli spiritosi!} di
\texttt{more}.

Le funzionalità di \texttt{less} sono sostanzialmente identiche a quelle di
\texttt{more}, e supporta anche tutti i comandi da tastiera illustrati in
precedenza, ma il programma consente degli spostamenti più comodi, potendo
navigare il contenuto del file avanti ed indietro con i tasti di freccia,
pagina su e giù, ecc. Il comando poi supporta funzionalità avanzate come la
possibilità di ridefinire dei \textit{keybinding}, di lanciare dei programmi
per pre-processare dei dati (ad esempio decomprimere al volo dei file
compressi), ecc. Per i dettagli si faccia al solito riferimento alla pagina di
manuale.

Un altro programma di visualizzazione, più utile in caso di file binari, è
\index{comando!\texttt{od}} \texttt{od}, (da \textit{\textbf{o}ctal
  \textbf{d}ump}) che permette di stampare il contenuto di un file in forma
numerica, usando vari formati: decimale, ottale (il default), esadecimale e
pure direttamente in semplice ASCII. La modalità in cui viene stampato il
contenuto è controllata dall'opzione \texttt{-t}, che prende come parametro
una stringa indicante il formato, il cui primo carattere indica il tipo di
rappresentazione scelta, secondo quanto riportato in
tab.~\ref{tab:cmd_od_format_types}. Nel caso si sia usata una forma numerica,
si può utilizzare un secondo carattere per indicare la dimensione in byte del
numero in questione.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Carattere} & \textbf{Formato} \\
    \hline
    \hline
    \texttt{a} & caratteri ASCII, coi caratteri non stampabili riportati 
                 tramite un nome simbolico.\\
    \texttt{c} & carattere ASCII, coi caratteri non stampabili riportati in
                 forma numerica preceduta dalla barra rovescia.\\
    \texttt{d} & decimale.\\
    \texttt{f} & virgola mobile.\\
    \texttt{o} & ottale.\\
    \texttt{u} & decimale senza segno.\\
    \texttt{x} & esadecimale.\\
    \hline
  \end{tabular}
  \caption{I caratteri indicanti il formato per la stampa dell'output del
    comando \texttt{od}.} 
  \label{tab:cmd_od_format_types}
\end{table}

Una seconda opzione che permette di modificare il formato di stampa di
\texttt{od} è \texttt{-A}, che stabilisce come deve essere stampato il numero
progressivo che indica la posizione nel file; l'opzione prende come parametro
uno dei caratteri \texttt{d}, \texttt{o}, \texttt{x}, o \texttt{n} dove i
primi tre hanno lo stesso significato riportato in
tab.~\ref{tab:cmd_od_format_types} mentre \texttt{n} indica che non deve
essere stampato nulla.  

Altre due opzioni utili sono \texttt{-j} che permette di iniziare la stampa a
partire da una certa posizione all'interno del file e prende come parametro il
numero di byte da saltare, e \texttt{-N} che permette di specificare,
passandolo come parametro, il numero di byte da stampare, altrimenti il
comando stampa tutto il contenuto del file. Per le altre opzioni ed i dettagli
di funzionamento del comando si faccia al solito riferimento alla pagina di
manuale.

Del tutto analogo ad \texttt{od} per funzionalità e utilizzo è il comando
\index{comando!\texttt{hexdump}} \texttt{hexdump} che esegue le stesse
operazioni ma che, nascendo come \textit{\textbf{h}exadecimal \textbf{d}ump},
di default stampa il risultato in formato esadecimale anziché ottale. Come il
precedente il comando, che può essere invocato anche come
\index{comando!\texttt{hd}} \texttt{hd}, prende una serie di opzioni che
consentono di controllare la visualizzazione, riportate nella seconda parte di
tab.~\ref{tab:cmd_hexdump_options}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-n \textsl{N}}&stampa solo il numero di caratteri indicato come
                  parametro (il default è stampare fino alla fine del file).\\
    \texttt{-s \textsl{N}}&inizia a stampare dal numero di caratteri indicato
                  come parametro rispetto all'inizio del file.\\
    \texttt{-e \textsl{str}}& indica una stringa di formattazione per l'uscita
                  del comando (per il formato si consulti la pagina di
                  manuale).\\
    \texttt{-v} & stampa il contenuto completo (in caso di righe consecutive
                  identiche di default queste vengono sostituite con una
                  riga di asterischi).\\ 
    \hline
    \texttt{-c} & stampa il contenuto in caratteri ASCII, coi caratteri non
                  stampabili riportati in forma numerica (o simbolica)
                  preceduti dalla barra rovescia.\\ 
    \texttt{-d} & stampa il contenuto in forma decimale intera (usando due
                  byte alla volta) con 8 valori per riga.\\ 
    \texttt{-b} & stampa il contenuto in forma ottale (con ciascun byte
                  indicato da tre cifre separate da spazi) con 16 valori per
                  riga.\\
    \texttt{-x} & stampa il contenuto in forma esadecimale (usando due
                  byte alla volta) con 8 valori per riga.\\
    \texttt{-C} & stampa il contenuto con una combinazione di esadecimale e
                  ASCII.\\ 
    \hline
  \end{tabular}
  \caption{Le principali opzioni di \texttt{hexdump}.} 
  \label{tab:cmd_hexdump_options}
\end{table}

Oltre a quelle di visualizzazione altre opzioni significative sono \texttt{-s}
e \texttt{-n} che consentono di indicare rispettivamente posizione di partenza
e numero di byte da stampare. Inoltre rispetto ad \texttt{od} il comando
consente di controllare il formato di stampa in maniera molto dettagliata, in
particolare l'opzione \texttt{-e} che consente di indicare una stringa di
formattazione. Per l'elenco completo delle opzioni ed i dettagli di
funzionamento, ed in particolare per il formato delle stringhe di
formattazione, si faccia riferimento alla pagina di manuale.

Un'altra particolare forma di visualizzazione del contenuto di un file viene
eseguita dal comando \index{comando!\texttt{tac}} \texttt{tac}, che serve a
stampare il contenuto di un file alla rovescia, cioè a partire dall'ultima
riga verso la prima.\footnote{si, l'idea era proprio quella di fare
  \texttt{cat} al contrario...} Il comando in realtà divide un file in campi
separati da un carattere, che di default è il ritorno a capo per cui i campi
vengono a coincidere con le righe; con l'opzione \texttt{-s} però si può
passare come parametro un diverso separatore, mentre con \texttt{-r} si può
usare come separatore una espressione regolare (vedi
sez.~\ref{sec:cmd_regular_expression}).  Per i dettagli conviene consultare la
pagina \textit{info} con \texttt{info tac} dato che la pagina di manuale è
molto sintetica.

Un'ultima forma particolare di visualizzazione del contenuto di un file è
quella ottenibile con il comando \index{comando!\texttt{wc}} \texttt{wc}, (da
\textit{\textbf{w}ord \textbf{c}ount}) che viene usato per contare linee,
parole e caratteri contenuti in un file. Il comando prende come argomento una
lista di file (se non se ne specificano al solito viene usato lo
\textit{standard input}) per ciascuno dei quali stampa il numero totale di
linee, di parole e byte. In genere il comando stampa tutte queste informazioni
insieme al nome del file, se ne sono specificati più di uno. Si può far
stampare solo il numero di linee, di parole o di byte rispettivamente con le
opzioni \texttt{-l}, \texttt{-w} e \texttt{-c}. L'opzione \texttt{-L} invece
stampa la lunghezza della linea più lunga. Al solito per tutti i dettagli sul
comando si consulti la pagina di manuale.

\subsection{I comandi di elaborazione dei contenuti dei file}
\label{sec:cmd_file_filter}

In questa sezione prenderemo in esame una serie di comandi che permettono di
filtrare e manipolare in maniera automatica il contenuto dei file. Questi
programmi costituiscono uno strumento estremamente potente e sono il cuore
della cosiddetta \textit{Unix toolbox}, in quanto il loro inserimento
all'interno di una concatenazione di comandi permette di eseguire delle
operazioni di elaborazione dei contenuti di un flusso di dati in maniera
rapida ed efficiente, costruendo, grazie alle funzionalità del
\textit{pipelining} della shell, quella \textsl{catena di montaggio} di cui
parlavamo in sez.~\ref{sec:shell_design}.

Una prima serie di possibili comandi di elaborazione sono quelli che
riguardano la suddivisione, in varie modalità, dei contenuti di un file.  I
primi due comandi che prenderemo in esame sono \index{comando!\texttt{head}}
\texttt{head} e \index{comando!\texttt{tail}} \texttt{tail}, che ci permettono
di selezionare e poi scrivere sullo \textit{standard output} rispettivamente
l'inizio e la fine di un file (o di una lista di file).  Entrambi i programmi
usano l'opzione \texttt{-n} per indicare il numero di linee totali da
selezionare (il default è 10), e l'opzione \texttt{-c} per effettuare la
selezione in byte invece che in linee.  Entrambi i comandi, quando non si
specifica nessun argomento, operano sullo \textit{standard input}.  Al solito
si faccia riferimento alla pagina di manuale per l'elenco completo delle
opzioni e la descrizione dettagliata dei comandi.

Abbiamo visto come ottenere l'inizio e la fine di un file, ma la nostra
cassetta degli attrezzi sembrerebbe mancare di un comando che ci permetta di
selezionare una sezione qualunque del file a partire da una certa riga
\texttt{N} per finire con un'altra \texttt{M}. In realtà questo ancora una
volta è facilmente ottenibile concatenando i due comandi precedenti; basterà
tagliare prima la testa del file con \texttt{head} e poi la coda con
\texttt{tail}, costruendo con l'ausilio della \textit{arithmetic expansion}
che abbiamo descritto in sez.~\ref{sec:shell_sintax} una linea di comando del
tipo:
\begin{Example}
head -n M file | tail -n $((M-N+1))
\end{Example}
%$

Vale la pena poi menzionare esplicitamente l'opzione \texttt{-f} di
\texttt{tail}, che quando usata fa sì che il comando non esca, e continui a
stampare ogni eventuale altro dato aggiunto in coda al file, permettendo così
di seguire la crescita di quest'ultimo.  Questa è una opzione molto utile per
tenere sotto controllo i file di log (vedi sez.~\ref{sec:syslog.conf}), ed in
generale tutti i file in cui altri programmi scrivono in coda i loro dati.

In sez.~\ref{sec:shell_IO_redirect} abbiamo visto come usare \texttt{cat} per
concatenare il contenuto di più file, per eseguire l'operazione inversa si può
usare \index{comando!\texttt{split}} \texttt{split}, che viene usato per
``\textsl{tagliare a fette}'' un file. Il comando prende come argomento il
file da ``\textsl{affettare}'', e lo suddivide in tanti file di dimensione
uguale che chiama progressivamente \texttt{xaa}, \texttt{xab}, \texttt{xac},
ecc.  Se non si specifica un argomento al solito \texttt{split} legge dallo
\textit{standard input}, consentendo così ad esempio di creare un file con un
comando e suddividerlo al volo con una \textit{pipe}. Dato che il comando crea
le sue \textsl{fette} in ordine alfabetico, per ricomporre il file originario
basterà usare \texttt{cat} con un comando del tipo \texttt{cat x* > file}.

Aggiungendo un secondo argomento dopo il nome del file da suddividere si può
specificare un prefisso diverso da \texttt{x} come intestazione dei nuovi file
creati dal comando. La dimensione dei file (il default è 1000 linee) viene
specificata con l'opzione \texttt{-l} se la si vuole in numero di linee o con
\texttt{-b} se la si vuole in numero di byte; quest'ultima opzione supporta
anche un valore del parametro con i suffissi \texttt{m} e \texttt{k} per
indicare rispettivamente megabyte e kilobyte.  Infine se due lettere non
bastano per indicizzare i file che si generano si può usare l'opzione
\texttt{-a} per specificarne un numero diverso. Un elenco delle principali
opzioni è riassunto in tab.~\ref{tab:cmd_split_options}, per tutti i dettagli
si faccia al solito riferimento alla pagina di manuale.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-b \textsl{N}}& specifica la dimensione delle ``\textsl{fette}''
                            in byte.\\ 
    \texttt{-a \textsl{N}}& specifica la lunghezza del suffisso.\\
    \texttt{-d}           & usa un suffisso numerico anziché alfabetico.\\
    \texttt{-l \textsl{N}}& specifica la dimensione delle ``\textsl{fette}''
                            in linee.\\ 
    \hline
  \end{tabular}
  \caption{Le principali opzioni del comando \texttt{split}.} 
  \label{tab:cmd_split_options}
\end{table}

Se si vuole \textsl{affettare} un file per colonne (cioè in
\textsl{verticale}) invece che per righe (in \textsl{orizzontale}) si può
usare il comando \index{comando!\texttt{cut}} \texttt{cut}.  Il comando opera
sul file passato come argomento, o sullo \textit{standard input}, rendendo di
nuovo possibile operazioni complesse e filtri ricorsivi; le colonne
selezionate verranno stampate sullo \textit{standard output}.

Con l'opzione \texttt{-c} si può creare la selezione scegliendo quali
caratteri inserire nel risultato in base alla loro posizione rispetto
all'inizio della riga.  L'opzione prende una lista di posizioni numeriche
separata da virgole, e supporta la presenza di intervalli indicati con due
numeri separati da un ``\texttt{-}'' (il comando conta da 1 per il carattere
ad inizio riga). Inoltre se si specifica un valore preceduto da ``\texttt{-}''
si selezionerà tutta la riga dall'inizio a quella posizione, e viceversa un
valore seguito da ``\texttt{-}'' selezionerà tutto da quella posizione a fine
riga. Così se ad esempio si vuole ottenere la stringa dei permessi che sta
all'inizio dall'output di \texttt{ls -l} basterà eseguire:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{ls -l *.tex | cut -c 1-10}
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
\end{Console}
%$

L'utilità del comando è che oltre ad una selezione basata su posizioni
assolute all'interno della riga, esso permette di effettuare la selezione
anche in termini di \textsl{campi} delimitati da un carattere qualunque che
può essere specificato con l'opzione \texttt{-d} (di default il comando usa
come separatore il carattere di tabulazione). In tal caso si effettuerà la
selezione di quali campi stampare con l'opzione \texttt{-f}, indicando i
numeri dei campi scelti con la stessa sintassi usata per \texttt{-c}, cioè con
liste separate da virgole ed intervalli. Così si potrà ad esempio stampare il
proprio \textit{user ID} con:\footnote{il formato del file
  \texttt{/etc/passwd} è trattato in sez.~\ref{sec:cfg_user_db}, e vedremo
  \texttt{grep}, che consente di effettuare la ricerca di una stringa in un
  file, in sez.~\ref{sec:cmd_regular_expression}.}
\begin{Console}
piccardi@anarres:~$ \textbf{cat /etc/passwd | grep piccardi | cut -d: -f 3}
1000
\end{Console}
%$

Si tenga presente che le selezioni per campi o caratteri sono alternative fra
loro, e che anche se si possono elencare i campi da stampare in qualunque
ordine, questi verranno comunque scritti nell'ordine in cui sono letti dal
file originale. Le opzioni principali del comando sono riportate in
tab.~\ref{tab:cmd_cut_options}, al solito per i dettagli di funzionamento e
l'elenco completo si consulti la pagina di manuale.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-b \textsl{N}}& specifica un intervallo di byte (sull'intero file). \\
    \texttt{-c \textsl{N}}& specifica un intervallo di caratteri.\\
    \texttt{-d \textsl{c}}& specifica il carattere delimitatore dei campi.\\
    \texttt{-f \textsl{N}}& specifica un intervallo di campi.\\
    \texttt{-s}           & stampa solo le righe che contengono il delimitatore.\\
    \texttt{-{}-output-delimiter= \textsl{str}} & usa la stringa \texttt{str}
                                                come delimitatore nell'output
                                                del comando.\\
    \hline
  \end{tabular}
  \caption{Le principali opzioni del comando \texttt{cut}.} 
  \label{tab:cmd_cut_options}
\end{table}

Oltre a suddividere o selezionare parte del contenuto di un file, esistono
molte situazioni in cui occorre eseguire manipolazioni di altra natura, ed un
secondo insieme di comandi è stato fornito a questo scopo.  Come contraltare a
\texttt{cut}, il comando \index{comando!\texttt{paste}} \texttt{paste}
permette di concatenare file diversi in colonna. Il comando prende come
argomenti i nomi di una serie di file, e produce in uscita un file diviso in
colonne, separate dal carattere di tabulazione, in cui i campi di una riga
sono costituiti dalle corrispondenti righe dei file in ingresso. Se non si
specifica nessun file il comando legge dallo \textit{standard input}, che può
essere usato anche all'interno di una sequenza di file indicandolo con
``\texttt{-}''.

Quando i file hanno dimensioni diverse il file prodotto sarà esteso alla
lunghezza, in righe, del più lungo dei file in ingresso, in cui le righe
finali avranno dei campi vuoti in corrispondenza alle righe mancanti nei file
più corti. % Questo comportamento può essere modificato usando l'opzione
% \texttt{-f} che ferma la generazione di nuove righe non appena si incontra la
% fine di uno dei file dati in ingresso.
% questa opzione pare non più supportata ...

Con l'opzione \texttt{-s} invece \texttt{paste} può effettuare una
\textsl{trasposizione} dei file, in cui il contenuto (in righe) di ciascuno di
essi viene messo in colonna su di un'unica riga. Se si usano più file in
ingresso saranno generate tante righe quanti sono i file.  Con l'opzione
\texttt{-d} si possono modificare i caratteri usati per la separazione delle
colonne, l'opzione prende come parametro una stringa i cui caratteri saranno
usati in sequenza come separatori fra le varie righe, nell'ordine in cui li si
sono indicati. Al solito i dettagli si trovano nella pagina di manuale, ma in
questo caso sono più esaurienti le informazioni sui comandi generici di Unix
disponibili nel sistema degli \textit{info files}, accessibili con
\texttt{info coreutils} (vedi sez.~\ref{sec:documentazione}).

Un altro comando che permette di eseguire una unione per righe è
\index{comando!\texttt{join}} \texttt{join}, che però opera solo su due file,
che devono essere passati come argomenti, ed esegue l'unione sulla base della
presenza di un campo comune, che viene ripetuto una sola volta nell'output
finale. In questo caso si può specificare l'uso dello \textit{standard input}
indicandolo con ``\texttt{-}'' negli argomenti, ma ovviamente solo per uno dei
due file di ingresso.

Il comando opera di default usando come separatori gli spazi, sia per la
suddivisione in colonne dei file in ingresso che per la scrittura dei
risultati in uscita, utilizzando la prima colonna come campo comune.
Quest'ultimo può essere cambiato per entrambi i file con l'opzione
\texttt{-j}, seguita dal numero della posizione; se il campo comune avesse
posizione diversa nei due file si può impostare quest'ultima in maniera
separata per ciascuno di essi rispettivamente con le opzioni \texttt{-1} e
\texttt{-2} (sempre seguite dal numero della posizione).

Il comando verifica se in entrambi i file è presente il campo comune e in tal
caso scrive in uscita una riga corrispondente, si tenga presente che il campo
deve corrispondere esattamente (ma si può usare l'opzione \texttt{-i} per
richiedere una corrispondenza \textit{case-insensitive}) e che la scansione è
eseguita a partire dal primo file una riga alla volta cercando un campo
corrispondente nel secondo, e che una volta trovata la corrispondenza la
ricerca prosegue, \textsl{in entrambi i file}, dalla riga seguente. Questo
significa ad esempio che se il campo della prima riga del primo file
corrisponde al campo della quarta riga del secondo file, la ricerca di
corrispondenza del campo della seconda riga del primo file inizierà a partire
dalla quinta riga del secondo, e l'eventuale presenza di una corrispondenza
nelle righe precedenti sarà ignorata.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-1 \textsl{N}}& specifica qual'è il campo comune nel primo file.\\
    \texttt{-2 \textsl{N}}& specifica qual'è il campo comune nel secondo
                            file.\\ 
    \texttt{-j \textsl{N}}& specifica qual'è il campo comune.\\
    \texttt{-i}           & la corrispondenza del campo comune è verificata in
                            modalità \textit{case insensitive}.\\
    \texttt{-e \textsl{tag}}& specifica un valore da mettere al posto dei
                            campi assenti.\\ 
    \texttt{-t \textsl{c}}& specifica un carattere da usare come separatore.\\
    \hline
  \end{tabular}
  \caption{Le principali opzioni del comando \texttt{join}.} 
  \label{tab:cmd_join_options}
\end{table}

Se ci sono campi vuoti in corrispondenza di un valore questi possono essere
riempiti con una stringa fissa indicata come parametro per l'opzione
\texttt{-e}, e si può cambiare il carattere usato come separatore dei campi
usando l'opzione \texttt{-t}. L'elenco delle opzioni principali è riportato in
tab.~\ref{tab:cmd_join_options}. Al solito si può fare riferimento alla pagina
di manuale, ma anche questo caso le informazioni più dettagliate sono
disponibili nel sistema degli \textit{info files}, accessibili con
\texttt{info coreutils}.

Un altro programma molto utile è \index{comando!\texttt{sort}} \texttt{sort},
che permette di ordinare il contenuto di un file. Il comando prende come
argomento un file e ne stampa il contenuto con le righe in ordine alfabetico.
Dato che se non si specifica nessun file il comando opera sullo
\textit{standard input}, può essere usato di nuovo in una catena di comandi
per riordinare l'uscita di un altro comando. Così se si vuole riordinare un
elenco basterà darlo in pasto a \texttt{sort}.

Le opzioni di \texttt{sort} permettono di controllare le modalità di
ordinamento, ad esempio con \texttt{-b} si può dire al comando di ignorare gli
spazi all'inizio delle righe, con \texttt{-r} di invertire l'ordinamento, con
\texttt{-n} di ordinare le stringhe che contengono numeri sulla base del
valore di questi e non di quello alfabetico (per avere 2 prima di 10), con
\texttt{-f} di non differenziare fra maiuscole e minuscole. Le principali
opzioni di \texttt{sort} sono riportate in tab.~\ref{tab:cmd_sort_options},
per l'elenco completo si faccia al solito riferimento alla pagina di manuale e
alla pagina \textit{info files}, accessibile con \texttt{info coreutils}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-b} & ignora gli spazio ad inizio riga.\\
    \texttt{-f} & esegui un ordinamento \textit{case insensitive}.\\
    \texttt{-n} & esegue un ordinamento numerico.\\
    \texttt{-r} & esegue l'ordinamento in ordine inverso.\\
    \texttt{-k \textsl{N,M}} & specifica quale colonna usare come chiave.\\
    \texttt{-t \textsl{c}} & imposta un separatore di campi.\\
    \texttt{-u} & elimina le righe duplicate.\\
    \hline
  \end{tabular}
  \caption{Le principali opzioni di \texttt{sort}.} 
  \label{tab:cmd_sort_options}
\end{table}

In generale \texttt{sort} esegue l'ordinamento a partire dall'inizio di
ciascuna riga, ma con l'opzione \texttt{-k} è possibile selezionare quale
sezione della riga usare per l'ordinamento. In questo caso si sottintende che
il file sia suddiviso in campi, di default il comando considera i campi
separati da un numero arbitrario di caratteri vuoti, come spazi e tabulatori,
ma si può specificare un carattere di separazione con \texttt{-t}, l'opzione
\texttt{-k} prevede che si indichino (per valore numerico progressivo) il
campo iniziale e quello finale separati da una virgola, ma il campo finale (e
la virgola di separazione) possono essere omessi nel qual caso \texttt{sort}
userà tutto il resto della riga. Così se ad esempio si ha in
\texttt{nominativi.txt} un elenco contenente i riferimenti di un gruppo di
persone, con nome, cognome e numero di telefono, si potrà ottenerne una
versione ordinata per cognome con il comando:
\begin{Example}
sort -k 2,2 nominativi.txt
\end{Example}


Un altro comando che permette di operare sul contenuto di un file è
\index{comando!\texttt{uniq}} \texttt{uniq}, che elimina linee adiacenti
uguali. Il comando prende come argomento un nome di file, ma se non viene
specificato niente legge lo \textit{standard input}, e stampa il risultato,
senza linee duplicate, sullo \textit{standard output}; usando due argomenti il
secondo viene usato come file di destinazione al posto dello \textit{standard
  output}.

Al solito varie opzioni permettono di controllare le modalità di funzionamento
del comando: con \texttt{-i} si può ignorare la differenza fra maiuscole e
minuscole, con \texttt{-s} si può specificare il numero di caratteri ad inizio
riga da non inserire nel confronto, ed infine con \texttt{-d} si può chiedere
ad \texttt{uniq} di stampare soltanto le linee duplicate.  Altre opzioni, al
solito dettagliate nella pagina di manuale, permettono anche selezioni più
complesse.

Di nuovo considerata a se stante, l'utilità di un comando come questo può
apparire limitata, ma basta pensare alle combinazioni con altri comandi per
apprezzarne la funzionalità.  Si consideri ad esempio la necessità di riunire
elenchi di parole contenuti in più file (supponiamo siano
\texttt{elenco1.txt}, \texttt{elenco2.txt}, ecc.). Lo scopo è quello di avere
un file con l'elenco completo in cui tutte le parole compaiono una volta sola;
questo può essere ottenuto in un batter d'occhio con un comando
come:\footnote{in realtà \texttt{sort} consente anche di rimuovere le righe
  duplicate con l'opzione \texttt{-u} e l'uso finale di \texttt{uniq} in
  questo caso non servirebbe.}
\begin{Example}
cat elenco*.txt | sort | uniq > elencofinale
\end{Example}


Un altro comando che si usa per manipolare il contenuto di un file è
\index{comando!\texttt{tr}} \texttt{tr}, il cui nome sta per
\textit{\textbf{tr}anslate}. Lo scopo del comando è quello di effettuare delle
sostituzioni dei caratteri. Come tutti i comandi esso opera direttamente su un
file qualora questo sia specificato a riga di comando altrimenti utilizza lo
\textit{standard input}, scrivendo il risultato sullo \textit{standard
  output}; in tal modo lo si può utilizzare come un \textsl{filtro} di
conversione.

Il comando può prendere uno o due argomenti. Il primo indica un insieme di
caratteri di cui eseguire la ricerca nel file, il secondo, quando presente,
indica la lista dei caratteri con cui il corrispondente carattere del primo
insieme deve essere sostituito. In genere quando si specificano due argomenti
questi devono specificare due insiemi almeno della stessa dimensione. Qualora
questo non avvenga il secondo insieme viene esteso ripetendone l'ultimo
carattere, a meno di non usare l'opzione \texttt{-t} che tronca invece il
primo insieme alle dimensioni del secondo. Se invece il secondo insieme è più
lungo vengono utilizzati solo i caratteri iniziali.

Qualora si specifichi l'opzione \texttt{-d} il secondo insieme viene ignorato,
e tutti i caratteri del primo insieme vengono cancellati. Se invece si
specifica l'opzione \texttt{-c} il primo insieme viene considerato come quello
dei caratteri che \textsl{non} devono corrispondere. Infine usando l'opzione
\texttt{-s} si possono ``\textsl{strizzare}'' preventivamente le ripetizioni
di un qualunque carattere del primo insieme trasformandole in un carattere
singolo (che poi potrà essere sostituito). L'elenco delle opzioni principali è
riportato in tab.~\ref{tab:cmd_tr_options}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-c} & seleziona i caratteri che non sono indicati nel primo
                  insieme.\\ 
    \texttt{-d} & cancella i caratteri indicati nel primo insieme.\\
    \texttt{-s} & rimpiazza le occorrenze ripetute dei caratteri del primo
                  insieme.\\ 
    \texttt{-t} & tronca il primo insieme alla lunghezza del secondo.\\
    \hline
  \end{tabular}
  \caption{Le principali opzioni di \texttt{tr}.} 
  \label{tab:cmd_tr_options}
\end{table}

Le liste dei caratteri in genere si possono esprimere direttamente con delle
stringhe, il comando però supporta anche le classi di caratteri definite in
tab.~\ref{tab:cmd_regexp_character_class}, e si possono usare gli
identificatori ivi riportati. Inoltre l'utilizzo del carattere di
\textit{escape} ``\texttt{\bslash}'' permette non solo di proteggere i
caratteri speciali, ma di inserire negli insiemi caratteri non stampabili
secondo quanto riportato in tab.~\ref{tab:cmd_tr_special_char}.  Per la
sintassi completa del comando ed i dettagli riguardo le varie forme che si
possono utilizzare per specificare gli insiemi dei caratteri si faccia
comunque riferimento alla pagina di manuale, al solito accessibile con
\texttt{man tr}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Espressione} & \textbf{Significato} \\
    \hline
    \hline
    \verb|\NNN|& carattere specificato col suo valore numerico ottale.\\
    \verb|\\|  & barra trasversa. \\
    \verb|\a|  & \textit{bell} (suona sul terminale).\\
    \verb|\b|  & cancella indietro (\textit{backspace}). \\
    \verb|\f|  & pagina nuova (\textit{form feed}).\\
    \verb|\n|  & a capo (\textit{new line}).\\
    \verb|\r|  & ritorno carrello (\textit{return}).\\
    \verb|\t|  & tabulazione orizzontale.\\
    \verb|\v|  & tabulazione verticale.\\
    \hline
  \end{tabular}
  \caption{Caratteri speciali ad uso del comando \texttt{tr}.}
  \label{tab:cmd_tr_special_char}
\end{table}

Analoghi a \texttt{tr}, ma con uno scopo molto più limitato, sono i due
programmi \index{comando!\texttt{expand}} \texttt{expand} e
\index{comando!\texttt{unexpand}} \texttt{unexpand} che servono
rispettivamente a convertire tabulazioni in spazi e viceversa. Entrambi
prendono l'opzione \texttt{-t}. Questa, se seguita da un numero singolo,
permette di specificare le dimensioni del tabulatore, mentre si possono
impostare le diverse posizioni delle tabulazioni se il parametro viene
specificato come lista di numeri separata da virgole. Per i dettagli di nuovo
si può fare riferimento alle rispettive pagine di manuale.

Un'altra serie di programmi attinenti l'elaborazione del contenuto dei file
sono quelli relativi a compressione e decompressione degli stessi. Nei primi
sistemi Unix veniva usato a questo scopo il comando \texttt{compress}, una
alternativa, nata sotto DOS, è invece \texttt{zip}. Entrambi i programmi sono
stati portati su Linux, anche se con alcune limitazioni dovute alla presenza
di brevetti software. 

Per questo motivo il comando di compressione più usato è
\index{comando!\texttt{gzip}} \texttt{gzip}, creato dal progetto GNU per
sostituire i due precedenti. La cosa però è possibile al 100\% soltanto per
\texttt{compress} che infatti viene normalmente sostituito con \texttt{gzip},
il problema con \texttt{zip} si presenta in caso di archivi di file, perché
\texttt{gzip} è in grado di operare soltanto su file singoli, per gestire
archivi su Unix infatti si usano altri programmi (vedi
sez.~\ref{sec:tar_cpio}), per cui in caso di archivio creato con \texttt{zip}
si dovrà utilizzare il comando \index{comando!\texttt{unzip}} \texttt{unzip}.

Se utilizzato senza opzioni il comando richiede come argomenti la lista dei
file da comprimere, una volta completata la compressione ciascun file verrà
sostituito dalla versione compressa, riconoscibile per il suffisso
\texttt{.gz}, mantenendo tutte le altre proprietà del file originale (tempi,
permessi e proprietario), qualora il nuovo file già esistesse il programma si
blocca chiedendo se deve sovrascriverlo. 

La decompressione di un file può essere effettuata invocando il comando con
l'opzione \texttt{-d}, ma è molto più comune eseguirla invocando il comando
stesso come \index{comando!\texttt{gunzip}} \texttt{gunzip}, è comune infatti
avere \texttt{gunzip} come \textit{hard link} a \texttt{gzip}, anche se alcune
distribuzioni preferiscono usare uno script di shell per lanciare \texttt{gzip
  -d}. In questo caso il file \texttt{.gz} verrà decompresso, ed una volta
riottenuto il file originale, cancellato.

Una ulteriore modalità con cui si può invocare il comando è come
\index{comando!\texttt{zcat}} \texttt{zcat}, che consente di decomprimere un
file inviando il risultato sullo \textit{standard output}, così da poterne
utilizzare i contenuti con una \textit{pipeline}. In questo caso il comando è
identico all'invocazione di \texttt{gzip -d -c}, dove l'opzione \texttt{-c}
consente di inviare il risultato del comando sullo \textit{standard output}, e
vale anche in questo caso quanto detto per \texttt{gunzip}, per cui anche
\texttt{zcat} può essere installato come \textit{hard link} a
\texttt{gzip}. Le principali opzioni del comando sono riportate in
tab.~\ref{tab:gzip_options}, per tutti i dettagli si consulti al solito la
pagina di manuale.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-c} & invia i risultati sullo \textit{standard output}.\\ 
    \texttt{-d} & decomprime anziché comprimere.\\
    \texttt{-l} & stampa le caratteristiche dei file compressi.\\ 
    \texttt{-t} & controlla l'integrità dei file compressi.\\
    \hline
  \end{tabular}
  \caption{Le principali opzioni di \texttt{gzip}.} 
  \label{tab:gzip_options}
\end{table}

Benché \texttt{gzip} sia un programma di compressione abbastanza efficiente e
veloce, l'algoritmo utilizzato non è uno dei più potenti, per questo motivo,
se si vogliono ottenere delle compressioni maggiori, è disponibile un altro
programma, \index{comando!\texttt{bzip2}} \texttt{bzip2}, che utilizza un
diverso algoritmo di compressione più efficiente ma anche molto più lento. In
questo modo è possibile ottenere una compressione maggiore a scapito di un
tempo di elaborazione per la compressione dei file più lungo. 

A parte l'algoritmo di compressione, e l'uso del suffisso \texttt{.bz2} per i
file compressi, le differenze con \texttt{gzip} sono minime: le opzioni
\texttt{-c}, \texttt{-d} e \texttt{-t} sono identiche, e sono disponibili come
alternative a \texttt{zcat} e \texttt{gunzip} gli equivalenti
\index{comando!\texttt{bzcat}} \texttt{bzcat} e
\index{comando!\texttt{bunzip2}} \texttt{bunzip2}. Anche in questo caso per i
dettagli si può fare riferimento alla pagina di manuale.

Un ulteriore programma di compressione ancora più sofisticato è
\index{comando!\texttt{xz}} \texttt{xz} basato sull'algoritmo LZMA, che nasce
come evoluzione del precedente \index{comando!\texttt{lzma}} \texttt{lzma}, di
cui rappresenta anche un sostituto. Presenta ottimi valori di compressione e
velocità rispetto a \texttt{bzip2}, ma comporta anche un consumo più elevato
di memoria, soprattutto in fase di compressione, che sulle macchine moderne è
meno critico ma può diventare problematico su macchine con risorse molto
limitate.  Sta riscuotendo un discreto successo e molti progetti, vista la
migliore compressione ottenibile anche rispetto a \texttt{bzip2}, stanno
iniziando ad adottarlo nella distribuzione di archivi compressi.

Il comando supporta, analogamente a \texttt{gzip}, l'uso di opzioni nella
forma \texttt{-\textsl{N}} dove \texttt{\textsl{N}} varia da 0 a 9 ed indica
un livello di compressione; il default usato è \texttt{-6}, che è una media
fra occupazione di memoria necessaria per la decompressione, e livello di
compressione. Dato che l'uso della memoria può essere critico (se non presente
in quantità sufficiente la decompressione fallisce), è possibile impostare un
limite massimo che non deve essere superato con \texttt{-{}-memlimit}, che in
fase di compressione fa si che il livello della stessa sia automaticamente
diminuito per garantire che il limite indicato non sia mai superato nel
decomprimere il file.

I file prodotti da \texttt{xz} sono nel nuovo formato LZMA2 ed usano
normalmente l'estensione \texttt{.xz}; come per \texttt{gzip} e \texttt{bzip2}
sono disponibili una serie di comandi ausiliari, tutti equivalenti all'uso di
\texttt{xz} con le opportune opzioni: per decomprimere un file si usa
\index{comando!\texttt{unxz}} \texttt{unxz}, e per scrivere sullo
\textit{standard output} il contenuto decompresso si usa
\index{comando!\texttt{xzcat}} \texttt{xzcat}. Il programma supporta anche la
sintassi del precedente \texttt{lzma} per gestire i file nel formato di
quest'ultimo,\footnote{in sostanza l'invocazione di \texttt{lzma} è
  equivalente ad eseguire \texttt{xz --format=lzma}.} per cui lo si può
invocare anche come \texttt{lzma}, \texttt{unlzma} e \texttt{lzcat}.

Trattiamo infine un terzo insieme di programmi che operano su file di testo
principalmente a scopo di riformattarne adeguatamente il contenuto. Il primo
di questi è \index{comando!\texttt{pr}} \texttt{pr} che serve a suddividere il
testo in pagine, numerate progressivamente dal programma stesso, in un formato
adatto alla stampa (da cui deriva il nome); il programma supporta numerose
opzioni volte a configurare in maniera diversa le modalità con cui viene
effettuata la suddivisione in pagine ed impostare le informazioni mostrate in
testa e coda delle stesse.

Il secondo programma è \index{comando!\texttt{fmt}} \texttt{fmt} che
riformatta il file in uscita paragrafo per paragrafo, permettendo di impostare
caratteristiche come indentazioni della prima riga e numero di spazi e
mantenere una lunghezza costante della riga. Di nuovo le varie modalità con
cui si può compiere la formattazione sono controllate dalle opzioni, per le
quali si rimanda alla pagina di manuale.

Il terzo programma è \index{comando!\texttt{fold}} \texttt{fold} che si limita
invece a spezzare le righe troppo lunghe, inserendo degli a capo, rispetto ad
una dimensione fissa da assegnare alle stesse, specificabile con l'opzione
\texttt{-w}. Questo è il più semplice dei comandi di formattazione, con forse
l'eccezione di \index{comando!\texttt{nl}} \texttt{nl}, che, come indica il
nome, serve a numerare le linee di ciascun file. Di nuovo si può fare
riferimento alle rispettive pagine di manuale per le singole opzioni.



\subsection{Ricerche ed elaborazioni sui file attraverso le espressioni
  regolari}
\label{sec:cmd_regular_expression}

\index{espressioni~regolari|(}

Abbiamo visto in sez.~\ref{sec:cmd_search} come \texttt{find} ci permetta di
trovare un file in base al nome e alle sue proprietà, in sostanza ci si è
limitati al nome e alle altre caratteristiche mantenute
nell'\textit{inode}. Non abbiamo parlato però di come effettuare ricerche
all'interno dei file stessi in base al loro contenuto.  Il comando che
fornisce questa funzionalità è \index{comando!\texttt{grep}} \texttt{grep},
che usato in forma elementare serve a cercare una stringa di caratteri
all'interno di uno o più file; la potenza di questo comando (e delle varie
versioni \textsl{evolute}, come \texttt{egrep}) è dovuta al fatto che consente
di fare ricerche estremamente evolute attraverso l'uso delle cosiddette
\textsl{espressioni regolari}.

Le \textsl{espressioni regolari}, abbreviate spesso in \textit{regex}, dal
loro nome in inglese, \textit{regular expression}, sono una specie di
estensione del sistema del \textit{filename globbing} che abbiamo illustrato
in sez.~\ref{sec:shell_sintax}, in cui, attraverso una serie di operatori, si
possono cercare corrispondenze fra stringhe con un grado di complessità
incredibilmente elevato. Questo le rende allo stesso tempo uno degli strumenti
più potenti ed uno degli argomenti più ostici del mondo Unix.

\index{espressioni~regolari|)}


L'uso elementare di \texttt{grep} è banale, il comando prende come primo
argomento la stringa da cercare seguita dal nome del file, o dei file se se ne
indica più di uno, in cui effettuare la ricerca. Il comando stampa in uscita
ogni riga del file nella quale ha rilevato una corrispondenza, e se si sono
indicati più file precede la riga con il nome del file. Ad esempio se si cerca
la stringa ``\textsl{Dispense}'' in alcuni file di questa guida si otterrà:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{grep Dispense net*.tex}
netadmin.tex:%% Dispense Amministrazione di rete
netbase.tex:%% Dispense Amministrazione di rete
netdns.tex:%% Dispense Amministrazione di rete
netinter.tex:%% Dispense Amministrazione di rete
netlpi.tex:%% Dispense Amministrazione di rete
\end{Console}
%$

Altre opzioni del comando sono \texttt{-i} che permette di effettuare ricerche
\textit{case insensitive}, \texttt{-r} che effettua la ricerca ricorsivamente
qualora nell'elenco dei file si sia indicata una directory, e \texttt{-v} che
inverte il risultato della ricerca (cioè stampa le righe che \textsl{non}
corrispondono alla stringa utilizzata). Le opzioni del comando sono moltissime
ma si sono riportate le più importanti in tab.~\ref{tab:cmd_grep_option}; al
solito si rimanda alla pagina di manuale per una descrizione più completa.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-b}& stampa la posizione nel file (in byte) in testa a ciascuna
                 riga in output. \\
    \texttt{-c}& non stampa le righe con le corrispondenze, ma solo il numero
                 totale delle stesse.\\
    \texttt{-E}& interpreta la stringa di ricerca come una espressione
                 regolare estesa.\\ 
    \texttt{-e}& indica esplicitamente la stringa di ricerca (serve a
                 proteggere stringhe di ricerca che iniziano con
                 ``\texttt{-}''). \\ 
    \texttt{-G}& interpreta la stringa di ricerca come espressione regolare
                 normale (il default). \\
    \texttt{-H}& stampa il nome del file in testa a ciascuna riga di output
                 (anche se si ricerca su un solo file).\\
    \texttt{-h}& sopprime la stampa del nome del file in testa a ciascuna riga
                 di output (quando sono più di uno).\\
    \texttt{-i}& non distingue fra maiuscole e minuscole.\\
    \texttt{-m \textsl{N}}& sospende la stampa in uscita dopo
                 \texttt{\textsl{N}} corrispondenze. \\
    \texttt{-n}& stampa il numero di riga del file in testa a ciascuna linea
                 in uscita. \\
    \texttt{-P}& interpreta la stringa di ricerca come espressione regolare in
                 stile Perl.\\
    \texttt{-r}& esegue la ricerca in forma ricorsiva, ripetendola anche per
                 tutti i file contenuti nelle sottodirectory di quelle passate
                 in ingresso (può essere specificata anche come \texttt{-R}).\\
    \texttt{-s}& sopprime la stampa degli errori al riguardo di file non 
                 leggibili o non esistenti. \\
    \texttt{-v}& inverte la selezione, stampa le linee non corrispondenti.\\
    \texttt{-{}-color}& colora diversamente il testo corrispondente
                 (disponibile solo nelle versioni più recenti di GNU
                 \texttt{grep}).\\
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{grep}.}
  \label{tab:cmd_grep_option}
\end{table}

Come molti altri comandi anche \texttt{grep} legge, qualora non gli si sia
passato nessun file come argomento, dallo \textit{standard input}, i risultati
al solito vengono scritti sullo \textit{standard output}. Diventa allora
evidente la sua utilità come filtro per selezionare a piacere, sulla base
delle opportune corrispondenze, le righe di un file. Si noti come facendo così
si possano effettuare ricerche sempre più mirate semplicemente concatenando in
successione diverse chiamate al comando.
 
\index{espressioni~regolari|(}

Come accennato la vera potenza di \texttt{grep} sta nel fatto che la ricerca
non viene semplicemente eseguita sulla corrispondenza ai caratteri contenuti
nella stringa passata come argomento, ma nel fatto che quest'ultima viene
interpretata, attraverso l'uso di alcuni caratteri riservati, come un
\textit{pattern} all'interno del file, indicato con una speciale sintassi che
è quella che costituisce le citate \textsl{espressioni regolari}.

La trattazione dettagliata delle espressioni regolari va ben al di là delle
possibilità di questo testo,\footnote{un buon testo sull'argomento è
  \cite{RegExp}.} qui ci limiteremo a fornire la descrizione delle
funzionalità più elementari. Una espressione regolare è in sostanza una
stringa di caratteri che identifica un \textit{pattern}, cioè una struttura
ordinata di caratteri e stringhe, di cui cercare l'occorrenza in un file
eseguendo l'operazione che viene usualmente chiamata \textit{pattern
  matching}.

In maniera analoga ad una espressione matematica una espressione regolare
viene costruita combinando delle espressioni elementari attraverso gli
opportuni operatori.  Gran parte dei caratteri (tutte le lettere, maiuscole o
minuscole, e i numeri) di una espressione regolare non viene interpretata, e
la loro presenza richiede semplicemente la presenza di un corrispondente
carattere nel contenuto su cui si effettua la ricerca, alcuni caratteri sono
invece riservati per svolgere il ruolo di operatori; uno di questi è la barra
rovescia ``\texttt{\bslash}'' con la quale si può richiedere l'interpretazione
letterale del carattere successivo (bloccandone l'interpretazione come
operatore).

Il carattere ``\verb|^|'' viene utilizzato per identificare l'inizio di una
riga, mentre il carattere ``\texttt{\$}'' serve ad identificarne la fine;
pertanto si potranno identificare i commenti in uno script di shell con
l'espressione regolare ``\verb|^#|'' mentre con l'espressione ``\verb|^$|'' si
identificheranno le righe vuote.  Il carattere ``\texttt{.}'' viene invece
utilizzato nelle espressioni regolari per indicare un carattere qualunque.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Classe} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{[:alnum:]} & lettere (maiuscole e minuscole, indipendenti dalla
                         localizzazione) e numeri. \\
    \texttt{[:alpha:]} & lettere (maiuscole e minuscole, indipendenti dalla
                         localizzazione). \\
    \texttt{[:cntrl:]} & caratteri di controllo. \\
    \texttt{[:digit:]} & caratteri numerici.\\
    \texttt{[:graph:]} & caratteri stampabili (esclusi gli spazi).\\
    \texttt{[:lower:]} & lettere minuscole.\\
    \texttt{[:print:]} & caratteri stampabili (caratteri vuoti compresi).\\
    \texttt{[:punct:]} & caratteri di punteggiatura.\\
    \texttt{[:space:]} & caratteri vuoti verticali ed orizzontali (spazi,
                         tabulatori, ritorni a capo).\\
    \texttt{[:upper:]} & lettere maiuscole.\\
    \texttt{[:xdigit:]}& cifre esadecimali.\\
    \hline
  \end{tabular}
  \caption{Le classi di caratteri utilizzabili nelle espressioni regolari.}
  \label{tab:cmd_regexp_character_class}
\end{table}

Alcune delle espressioni usate nel \textit{filename globbing} di
sez.~\ref{sec:shell_sintax} si ritrovano anche nelle espressioni regolari,
anche se in questo caso assumono un significato leggermente diverso e per
questo sono spesso causa di confusione ed errori. In particolare le parentesi
quadre vengono utilizzate come nel \textit{filename globbing} per indicare una
lista o un intervallo di caratteri (ad esempio ``\texttt{[aeiou]}'' indica le
vocali e ``\texttt{[a-z]}'' le minuscole), la differenza col \textit{filename
  globbing} è che in questo caso il carattere ``\verb|^|'' messo all'inizio
viene interpretato come inversione della lista seguente (ad esempio con
``\verb|[^A-Z]|'' si indicano tutti i caratteri che non siano una lettera
maiuscola).  Oltre a liste e intervalli specificati direttamente si possono
indicare fra parentesi quadre una serie di \textsl{classi} predefinite di
caratteri con le espressioni riportate in
tab.~\ref{tab:cmd_regexp_character_class}.

Anche i caratteri ``\texttt{*}'' e ``\texttt{?}'' assumono un significato
simile a quello del \textit{filename globbing}, ma nel caso delle espressioni
regolari questo accade perché essi vanno a far parte di un gruppo particolare
di operatori che sono chiamati \textsl{operatori di ripetizione}, riportati in
tab.~\ref{tab:cmd_regexp_repetition_operator}.  Gli operatori di ripetizione
si applicano all'oggetto che li precede (che sia un carattere singolo o una
espressione complessa) e richiedono che l'occorrenza dello stesso avvenga un
certo numero di volte, nel caso di ``\texttt{*}'' questo può essere un numero
qualunque (compreso nessuna) mentre con ``\texttt{?}'' si richiede che sia al
più una volta (e di nuovo lo zero è compreso). Spesso risulta utile l'uso
dell'operatore ``\texttt{+}'' che richiede la presenza di almeno una volta.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Operatore} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{?}      & l'espressione precedente può corrispondere zero o una 
                      volta. \\
    \texttt{*}      & l'espressione precedente può corrispondere da zero ad un
                      qualsiasi numero di volte. \\
    \texttt{+}      & l'espressione precedente può corrispondere da uno ad un
                      qualsiasi numero di volte. \\
    \texttt{\{n\}}  & l'espressione precedente deve corrispondere esattamente 
                      \texttt{n} volte. \\
    \texttt{\{n,\}} & l'espressione precedente deve corrispondere \texttt{n} 
                      o più volte. \\
    \texttt{\{n,m\}}& l'espressione precedente deve corrispondere fra  
                      \texttt{n} e \texttt{m} volte. \\
    \hline
  \end{tabular}
  \caption{Gli \textsl{operatori di ripetizione} nelle espressioni regolari.}
  \label{tab:cmd_regexp_repetition_operator}
\end{table}

Questo significato è di nuovo leggermente diverso da quello presente nel
\textit{filename globbing}, in particolare una espressione come
``\texttt{ab*}'' nel primo caso seleziona tutti i file il cui nome inizia per
``\texttt{ab}'' seguito da un numero qualunque di altri caratteri qualsiasi,
mentre nel secondo caso corrisponde ad una linea che contenga una
``\texttt{a}'' seguita da un numero qualunque (compreso zero) di
``\texttt{b}'', per cui anche una stringa come ``\texttt{ac}''
corrisponderebbe.  Per riottenere lo stesso significato precedente con una
espressione regolare occorrerebbe usare la stringa ``\texttt{ab.*}'', in
questo modo si richiede la presenza iniziale di entrambe le lettere
``\texttt{a}'' e ``\texttt{b}'' seguite da un qualunque numero (indicato da
``\texttt{*}'') di un qualunque altro carattere (indicato da ``\texttt{.}'').

Negli esempi appena mostrati gli operatori di ripetizione sono applicati solo
al carattere che li precede, è possibile però applicarli ad una intera
espressione regolare mettendola fra parentesi tonde, usando quello che viene
chiamato un \textsl{raggruppamento}. Ad esempio per trovare in questo testo
gli errori di battitura in cui si era scritto due volte la parola \texttt{una}
si è usato il comando:
\begin{Console}
piccardi@hain:~/truedoc/corso$ \textbf{grep -E '(una ){2,}' *.tex}
shell.tex:mentre nel secondo caso corrisponde ad una una linea che contenga una
\end{Console}
%$
dove appunto si è richiesto che l'occorrenza della stringa ``\texttt{una }''
avvenisse almeno due volte di fila.

Un raggruppamento viene a costituire quello che viene chiamato un
\textit{subpattern}; e non solo si può richiedere, con l'uso degli operatori
di ripetizione la presenza multipla di uno stesso \textit{pattern}, ma si può
anche usare l'operatore ``\texttt{|}'' posto fra due raggruppamenti per
richiedere la presenza alternativa di uno di essi. Così si può richiedere la
presenza della parola \texttt{free} o della parola \texttt{copyleft} nella
stessa riga con:
\begin{Console}
piccardi@hain:~$ \textbf{grep '\bslash(free\bslash|copyleft\bslash)' /usr/share/common-licenses/GPL-3}
  The GNU General Public License is a free, copyleft license for
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
...
\end{Console}
%$

In questo caso però si ha una complicazione e la sintassi varia se si usa la
sintassi delle cosiddette \textsl{espressioni regolari semplici}, il default,
nella quale le parentesi tonde e la ``\texttt{|}'' devono essere protetti
all'interno dell'espressione regolare stessa con la barra trasversa
``\texttt{\bslash}''.  Si noti infatti come si sia anche espressa quest'ultima
fra degli apici singoli per bloccare l'interpretazione degli stessi caratteri
da parte della shell. Se invece si usa la sintassi delle \textsl{espressioni
  regolari estese} (attivate con l'opzione \texttt{-E} di \texttt{grep}) la
protezione all'interno dell'espressione non è necessaria, ma va comunque
mantenuta quella nei confronti dell'interpretazione da parte della shell.

L'uso dei \textit{subpattern} ha poi un'ulteriore vantaggio, e cioè che tutte
le volte che uno di questi viene trovato, il suo valore viene memorizzato in
un elenco progressivo (secondo la sua posizione nell'espressione regolare) e
detto valore può essere referenziato (e riutilizzato all'interno della stessa
espressione) con l'uso delle sequenze speciali ``\verb|\1|'', ``\verb|\2|'',
ecc.  Così se ad esempio si vogliono trovare tutte le righe in cui compare due
volte, in posizione qualsiasi, una stessa identica combinazione di almeno 10
caratteri si potrà utilizzare l'espressione:
\begin{Console}
piccardi@hain:~$ \textbf{grep -E '(.\{10,\}).*\bslash{1}' /usr/share/common-licenses/BSD}
3. Neither the name of the University nor the names of its contributors
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\end{Console}
%$
dove fra parentesi si è richiesta la selezione di 10 caratteri consecutivi
qualunque e poi si è richiesto che la stessa selezione di caratteri comparisse
di seguito sulla stessa linea (con interposti un numero qualunque di altri
caratteri).

Come si può notare la selezione ottenuta può non essere immediata da capire,
con le ultime versioni di \texttt{grep} viene però in aiuto l'opzione
\texttt{-{}-color} che permette di stampare in un colore diverso la sezione
della riga che corrisponde, così da rendere più evidente l'effetto
dell'espressione regolare, cosa che può risultare di grande aiuto quando si
eseguono selezioni complesse e ci si trova a che fare con risultati
inaspettati.

%TODO: ampliare trattando i word boundary, \s \b ecc.

\index{espressioni~regolari|)}

Se \texttt{grep} utilizza le espressioni regolari per eseguire delle ricerche
sui contenuti di un file, consentendo selezioni molto complesse, un altro
comando, \index{comando!\texttt{sed}} \texttt{sed}, il cui nome sta per
\textit{\textbf{s}tream \textbf{ed}itor} le usa per effettuare manipolazioni
del contenuto.  Il programma serve per eseguire una serie di trasformazioni su
un flusso di dati, analoghe a quelle che potrebbero essere fatte usando un
normale editor su un file. Questo consente di poter utilizzare il comando in
una catena di \textit{pipe} che mettano in grado di effettuare modifiche anche
molto complesse nel passaggio dei dati dallo \textit{standard input} allo
\textit{standard output}.

Il comando prende come primo argomento una \textsl{espressione di editing} che
indica le operazioni da eseguire, a meno che non la si sia specificata nel
contenuto del file indicato con l'opzione \texttt{-f} o come parametro per
l'opzione \texttt{-e}. I restanti argomenti, se presenti, indicano i file su
cui applicare la suddetta espressione; se non è presente nessun altro
argomento lo script viene applicato sullo \textit{standard input}. Le
principali opzioni sono riportate in tab.~\ref{tab:cmd_sed_options}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-e \textsl{expr}}& indica esplicitamente che l'argomento seguente
                 è l'espressione contenente i comandi di
                 editing da applicare.\\
    \texttt{-f \textsl{file}}& indica un file contenente l'espressione dei
                 comandi di editing.\\
    \texttt{-n}& sopprime la stampa del \textit{pattern space} che avviene
                 alla fine del processo di ogni riga.\\
    \texttt{-r}& usa le espressioni regolari estese.\\ 
    \texttt{-i [\textsl{suf}]}& effettua la sostituzione sovrascrivendo
                 direttamente il file, eventualmente creando un backup se si è
                 specificato il suffisso \texttt{\textsl{suf}} opzionale.\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{sed}.}
  \label{tab:cmd_sed_options}
\end{table}

A meno di non utilizzare l'opzione \texttt{-n} il comando stampa tutto quanto
è stato letto in ingresso con le eventuali modifiche apportate sullo
\textit{standard output}. È così possibile salvare il risultato del filtraggio
redirigendo l'output del comando. L'opzione \texttt{-n} è fornita per
permettere, all'interno dei vari comandi, di eseguire una stampa in uscita
solo quando lo si ritiene opportuno, ed ottenere pertanto un risultato
diverso. Con l'opzione \texttt{-i} si può sovrascrivere il file ``\textsl{sul
  posto}'', evitando una copia esterna,\footnote{si ricordi che redirigere lo
  \textit{standard output} su un file ne comporta il troncamento, se lo si
  facesse sul file che si sta modificando si potrebbe incorrere nelle
  conseguenze sottolineate in sez.~\ref{sec:shell_IO_redirect}.} col rischio
di perdere il contenuto precedente, per questo l'opzione supporta la
possibilità di specificare un parametro che indichi il suffisso da apporre al
nome del file per ottenere un backup della versione originale.

La potenza di \texttt{sed} sta nella grande flessibilità dei comandi che
possono essere dati tramite l'espressione di editing, alcuni di questi infatti
utilizzano le espressioni regolari per individuare dei \textit{pattern} nel
file, ed operare su di essi compiendo sostituzioni, cancellazioni, ecc.

Le espressioni di editing sono normalmente divise in \textsl{indirizzi} e
\textsl{comandi}. Un indirizzo esprime l'insieme delle righe del file
originario a cui si applica il successivo comando. Un singolo indirizzo indica
la riga cui si applica il comando, con due indirizzi separati da una virgola
si indica un intervallo di righe, mentre quando, come nella maggior parte dei
casi, non si specifica nessun indirizzo, il comando si applica a tutte le
righe del file. Infine se ad un indirizzo si fa seguire (prima del comando) il
carattere ``\texttt{!}'' la selezione delle righe viene invertita.

In genere un indirizzo viene specificato tramite il numero della relativa riga
(ad esempio ``\texttt{10}'' indica la riga 10, ``\texttt{5,15}'' indica le
righe dalla quinta alla quindicesima e ``\texttt{3,7!}'' tutte le righe
escluse quelle nell'intervallo fra la terza e la settima. Sono però possibili
delle selezioni più complesse, come ``\texttt{\$}'' che indica l'ultima riga
del file, o ``\texttt{/regexp/}'' che seleziona le righe corrispondenti ad una
espressione regolare messa fra le due barre; se usato in questo modo, senza
dare nessun comando, \texttt{sed} agisce in maniera sostanzialmente identica a
\texttt{grep}. Un elenco delle principali forme con cui si può specificare un
indirizzo è riportato in tab.~\ref{tab:cmd_sed_address}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Espressione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{N}       & selezione la \texttt{N}-sima riga.\\
    \texttt{N,M}     & seleziona le righe dalla \texttt{N} alla \texttt{M}.\\
    \texttt{N\tild M}& selezione le righe a partire dalla \texttt{N}-sima a
                       passi di \texttt{M}.\\ 
    \texttt{/regexp/}& seleziona le righe che corrispondono all'espressione
                       regolare \texttt{/regexp/}.\\
    \texttt{\$}      & seleziona l'ultima riga del file.\\
    \texttt{N,+M}    & seleziona \texttt{M} righe a partire dalla
                       \texttt{N}-sima.\\
    \hline
  \end{tabular}
  \caption{Espressioni per specificare un indirizzo al comando \texttt{sed}.}
  \label{tab:cmd_sed_address}
\end{table}

Una volta specificato l'\textsl{indirizzo} la seconda parte di una espressione
di editing è composta da un \textsl{comando}. Un comando viene sempre
introdotto da un carattere di controllo, seguito da eventuali parametri. I
comandi possono essere ripetuti e raggruppati con l'uso delle parentesi
graffe, ed in genere vengono scritti uno per riga e possono essere letti da un
file con l'opzione \texttt{-f}.

Per capire l'azione dei vari comandi occorre capire come \texttt{sed} effettua
la manipolazione dei dati e dove questi sono mantenuti. Quando una riga viene
letta da un file essa viene posta nel cosiddetto \textit{pattern space} dove
vengono effettuate tutte le operazioni e la manipolazione del contenuto: è
cioè nel \textit{pattern space} che si troveranno le modifiche eseguite al
contenuto originale dalle operazioni di \texttt{sed}. Il comando prevede
inoltre la presenza di un altro spazio, chiamato \textit{hold space}, che
inizialmente è vuoto, e dove è possibile inviare dati a partire dal
\textit{pattern space} per poterli riprendere successivamente; questo permette
operazioni complesse in cui i dati sono opportunamente spostati e ricombinati
all'interno di detti \textsl{spazi}.

L'elenco dei comandi più comuni è riportato in tab.~\ref{tab:cmd_sed_command}
ma \texttt{sed} ne supporta molti altri. Un elenco completo con una
descrizione sommaria si può trovare nella pagina di manuale, ma la
documentazione completa, fornita anche di parecchi esempi, è disponibile solo
nelle pagine \textit{info}, accessibili con \texttt{info sed}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Espressione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{a}   & aggiunge una riga dopo quella selezionata.\\
    \texttt{d}   & cancella il \textit{pattern space} e passa al ciclo
                   seguente.\\
    \texttt{i}   & inserisce una riga al di sopra di quella selezionata.\\
    \texttt{p}   & stampa il \textit{pattern space}.\\
    \texttt{q \textsl{N}} & esce con codice di uscita pari a
                            \texttt{\textsl{N}}.\\ 
    \texttt{s}   & sostituisce il testo corrispondente ad una espressione
                   regolare con un altro testo.\\
    \hline
  \end{tabular}
  \caption{Principali espressioni di comando per \texttt{sed}.}
  \label{tab:cmd_sed_command}
\end{table}

Il più importante ed utilizzato, e l'unico che tratteremo esplicitamente, dei
comandi di \texttt{sed} è ``\texttt{s}'' che permette di sostituire una
sezione di testo nel \textit{pattern space} con un'altra. La sintassi del
comando è nella forma \texttt{s/ricerca/sostituzione/} dove al posto del
carattere ``\texttt{/}'' si può usare un carattere qualsiasi che viene ad
assumere il ruolo di delimitatore, questo consente di usare un altro carattere
quando nella stringa di ricerca o di sostituzione appare la stessa
``\texttt{/}'' (ad esempio in caso di \textit{pathname}). In questa forma
elementare il comando rimpiazza (all'interno del \textit{pattern space}) la
prima occorrenza della stringa \texttt{ricerca} con la stringa
\texttt{sostituzione}.

La potenza del comando sta nel fatto che la stringa di ricerca è in realtà una
espressione regolare, pertanto diventa possibile fare selezioni estremamente
complesse; inoltre si possono utilizzare i \textit{subpattern} già visti con
\texttt{grep} per selezionare pezzi di testo che possono essere riutilizzati
nella stringa di sostituzione con le usuali espressioni \verb|\1|, \verb|\2|,
ecc. consentendo così manipolazioni molto sofisticate.

Dopo la ``\texttt{/}'' finale si possono specificare degli ulteriori
sottocomandi, ad esempio usando ``\texttt{g}'' si indica al comando di
sostituire tutte le occorrenze della stringa di ricerca, e non solo la prima,
con ``\texttt{p}'' si richiede la stampa del \textit{pattern space} (si usa in
genere in combinazione con l'opzione \texttt{-n} per far stampare solo le
righe modificate) mentre specificando un numero ``\texttt{N}'' si esegue la
sostituzione solo per la \texttt{N}-sima corrispondenza trovata, con
``\texttt{i}'' invece si richiede che la ricerca sia
\textit{case-insensitive}.



\section{Gli editor di testo}
\label{sec:editor}

Si è preferito mantenere in una sezione separata la trattazione di una classe
di programmi, quella degli \textit{editor} di testo, che vengono a costituire
uno dei principali strumenti usati da tutti gli amministratori di sistema. Lo
scopo di questa sezione è quello di mettere il lettore in grado di cavarsela
con i principali editor disponibili in tutte le distribuzioni, poi con il
tempo e l'esperienza ognuno finirà con l'adottarne uno come preferito.


\subsection{Introduzione}
\label{sec:motivazioni}

Una delle caratteristiche fondamentali di un sistema unix-like, per le ragioni
che tratteremo in dettaglio in sez.~\ref{sec:cfg_general}, è quella di
mantenere le configurazioni dei programmi all'interno di semplici file di
testo. Per questo motivo probabilmente il programma più utilizzato dai
professionisti nell'amministrazione di sistema per configurare i servizi è
l'\textit{editor} di testi.

Infatti anche se la disponibilità di strumenti che permettono le più comuni
operazioni di amministrazione tramite una interfaccia grafica sta crescendo,
questi in genere mettono a disposizione solo un limitato numero di opzioni, e
non danno mai il completo controllo sul comportamento di un programma, che si
può ottenere soltanto operando direttamente sui file di configurazione.  Per
questo motivo l'\textit{editor}, cioè un programma che permetta di leggere
file di testo e modificarne il contenuto, diventa il principale strumento
dell'amministrazione di sistema.

Inoltre quando un qualche problema sul disco, o il classico \texttt{rm -fR}
dato da \textit{root} un po' troppo allegramente, avrà danneggiato qualche
file essenziale o bloccato il sistema all'avvio, sarà sempre possibile usare
una distribuzione di recupero avviata da CD o da chiavetta USB dove gli
strumenti grafici potrebbero non essere disponibili. E quand'anche si usasse
una delle tante distribuzioni che sono in grado di fornire un desktop
completo, le configurazioni sul sistema danneggiato andrebbero comunque
effettuate a mano dato che anche se il sistema fosse dotato degli strumenti
grafici di amministrazione necessari, questi opererebbero sul sistema avviato,
non su quello danneggiato.

Infine, anche se la diffusione della banda larga riduce il problema, usare una
interfaccia grafica da remoto resta sempre, considerazioni di sicurezza a
parte, estremamente lento (e sostanzialmente impossibile senza una buona
ADSL), mentre con la riga di comando si può usare un terminale remoto e fare
tutto quello che si vuole anche con la banda fornita da un semplicissimo modem
analogico.

Dato che l'editor di testi ha sempre avuto questo ruolo fondamentale, è stato
uno dei principali programmi applicativi, sviluppato fin dagli esordi di Unix.
Per questo, come per molte altre applicazioni di uso generale, ne esistono
molte versioni, con i nomi più pittoreschi, che pur svolgendo lo stesso
compito di base (la modifica dei file di testo) vanno da quelli dotati solo
delle funzionalità più elementari, come \texttt{ed}, che permette di operare
solo su una linea alla volta,\footnote{è probabilmente il primo editor
  sviluppato in ambiente Unix; per questa caratteristica viene chiamato
  ``\textsl{editor di linea}'', ed ha origine ai tempi in cui i terminali
  erano delle telescriventi; benché oggi nessuno sia così masochista da usarlo
  direttamente, i suoi comandi si ritrovano in altri editor e pure in
  programmi come \texttt{sed}.}  ai più complessi e sofisticati, come
\texttt{emacs} che ha una quantità infinita di funzionalità diverse e viene
paragonato da alcuni esagerati ad un secondo sistema operativo.

Nel prosieguo di questa sezione daremo una breve panoramica sull'uso dei più
comuni editor di testo, ma restando nell'ottica dell'amministrazione di
sistema tratteremo esclusivamente di editor accessibili da \textit{console}, e
quindi utilizzabili anche attraverso connessioni remote con dei semplici
modem.  Non entreremo nei dettagli dell'uso dei singoli editor, ci limiteremo
a esporre quali sono i comandi base per leggere, modificare e scrivere su un
file di testo.

La scelta dell'editor resta comunque una scelta personale, che genera spesso
clamorose ``\textsl{guerre di religione}'' fra le fazioni dei sostenitori dei
diversi editor. Particolarmente virulente sono quelle fra i sostenitori di
\texttt{emacs} e \texttt{vi}, i più blasonati (per numero di utenti e
tradizione di utilizzo) fra gli editor di testi.


\subsection{Un editor evoluto: \texttt{emacs}}
\label{sec:emacs-e-xemacs}

Per molti \index{editor!\texttt{emacs}} \texttt{emacs} è l'editor. Il suo nome
tutt'altro che immediato in teoria starebbe per \textit{\textbf{e}xtensible
  \textbf{mac}ro \textbf{s}ystem}, ma quando la memoria era molto poca è stato
ribattezzato in \textit{\textbf{e}ight \textbf{m}egs \textbf{a}nd
  \textbf{c}onstantly \textbf{s}wapping}, oppure, facendo riferimento
all'abbondante uso di tasti di modifica, \textit{\textbf{e}scape \textbf{m}eta
  \textbf{a}lt \textbf{c}ontrol \textbf{s}hift}.

Sicuramente come editor è il più potente, dentro \texttt{emacs} si può davvero
fare di tutto: navigare fra i file e in Internet, leggere la posta e le news
di \textit{Usenet}, programmare (con evidenziazione della sintassi e
scorciatoie ai costrutti principali di qualunque linguaggio), fare debug,
scrivere un testo come questo, giocare (a tetrix o a qualche avventura
testuale), ed anche farsi psicanalizzare dal ``\textit{doctor}''.\footnote{si
  provi ad eseguire \texttt{M-x doctor}...}

Qualunque cosa sia possibile fare con del testo, con \texttt{emacs} si fa,
infatti l'editor è programmabile in un dialetto specifico del Lisp, (un
linguaggio funzionale estremamente potente che consente una enorme
espandibilità del programma) e per un qualunque compito specifico sono state
create le estensioni più varie in grado di eseguire operazioni complesse,
gestire automatismi, abbellire la visualizzazione, ecc.

Tutto questo ha ovviamente un costo, ed infatti i detrattori di \texttt{emacs}
ne lamentano la pesantezza, ma data la diffusione e la potenza dello
strumento, il fatto che le distribuzioni su dischetto ormai sono passate di
moda, e la mia preferenza personale nei suoi confronti, ne parleremo più
estesamente considerato poi che molti altri editor ne hanno copiato la
sintassi e le modalità d'uso, ed alcuni programmi forniscono modalità di
comando \textsl{compatibili}, come la shell, che usa le stesse combinazioni di
tasti per l'editing della riga di comando, come abbiamo visto in
sez.~\ref{sec:shell_sintax}.

Inoltre sia \texttt{emacs}, che il cugino \texttt{xemacs}, che nacque proprio
per questo, sono editor usabili direttamente anche dall'interfaccia grafica,
nel qual caso verranno forniti all'utente gli usuali menu a tendina in cima
alla finestra, attraverso i quali si potranno trovare buona parte delle
funzionalità di cui essi dispongono.

\begin{figure}[!htb]
\centering
\includegraphics[scale=0.5]{images/emacs}
\caption{Schermata di avvio dell'editor \texttt{emacs}.}
\label{fig:base_emacs_screen}
\end{figure}

Come per tutti gli editor una sessione di \texttt{emacs} inizia invocando il
comando seguito dal nome del file da modificare; in tal caso si otterrà una
finestra come quella mostrata in fig.~\ref{fig:base_emacs_screen}. Nella prima
riga si trova il \textsl{menu} dei comandi, ad esso segue la sezione
principale, dove compare il testo del file ed in cui ci si muove con le
frecce, terminato da una \textsl{barra di stato} in cui compaiono varie
informazioni (il nome del file, se sono state fatte modifiche, ecc.).  Nella
riga finale viene tenuto il cosiddetto \textit{minibuffer}, in cui compaiono
brevi messaggi (come nell'esempio, che riporta la scritta
\texttt{(Updating...done)}) ed in cui si scrivono gli argomenti dei comandi
più complessi.

Uno dei concetti fondamentali di \texttt{emacs} è quello di \textit{buffer},
qualunque porzione di testo venga utilizzata da \texttt{emacs}, con
l'eccezione del \textsl{menu} e della \textsl{barra di stato}, è mantenuta in
un \textit{buffer}, sia che si tratti di un file che si è aperto per lavorarci
sopra, che del testo generato automaticamente nelle operazioni dell'editor
(come le liste dei file da scegliere che compaiono quando si usa
l'autocompletamento). Anche il \textit{minibuffer} è un buffer, con la
peculiarità di essere posizionato sull'ultima riga ed essere utilizzato per
l'interazione con i comandi.

In genere un buffer viene visto su una \textsl{finestra} che ne mostra il
contenuto ed è terminata da una barra di stato (nell'esempio ce n'è solo una),
ma all'interno di una stessa istanza dell'editor possono anche esserci più
\textsl{finestre} che possono essere aperte sullo stesso buffer o su buffer
diversi; questo vuol dire che ad esempio la sezione centrale di
fig.~\ref{fig:base_emacs_screen} può venire divisa in due.  Questo permette,
anche operando in \textit{console}, di lavorare su due o più finestre, dato
che ciascuna finestra può a sua volta essere suddivisa a piacere, con il solo
problema che se si creano troppe finestre non si vedranno altro che barre di
stato.

All'interno di una finestra ci si può spostare con le frecce e gli altri tasti
di spostamento e scrivere del testo, questo verrà sempre inserito nella
posizione in cui si trova il cursore. Inoltre \texttt{emacs} prevede una
grande quantità di combinazioni di tasti per andare avanti ed indietro, spesso
tutt'altro che intuitive per chi proviene da altri sistemi, questo è una
conseguenza del fatto che il programma è nato quando ancora le tastiere non
avevano né frecce né altri tasti di funzione. In genere il testo viene
inserito spostando quanto già presente nel file, a meno di non porsi nella
modalità di sovrascrittura premendo il tasto INS (verrà notificato nella barra
di stato) da cui si esce ripremendo lo stesso tasto.

I comandi invece vengono dati con delle combinazioni che prevedono la
pressione contemporanea di un \textsl{tasto modificatore} (si chiamano così i
tasti che hanno un effetto solo quando sono premuti in contemporanea ad altri
tasti, come il tasto per la maiuscole, il \textit{control}, ecc.) e di una
lettera. Molti comandi inoltre prevedono l'uso di due combinazioni di tasti
eseguite in successione.  Data la complessità e la grande quantità di comandi
esistono due modificatori per i comandi, il primo è il classico
\textit{control} ed il secondo è \textit{alt} il cui uso può essere simulato,
per le tastiere che non ce l'hanno, premendo prima il tasto di \textit{escape}
(ESC), e poi la lettera relativa.

Come già visto in sez.~\ref{sec:struct_job_control}, dove la si è usata senza
formalizzarne la definizione, per indicare la pressione contemporanea di un
modificatore con un tasto qualunque ``\texttt{x}'' utilizzeremo una notazione
del tipo \texttt{C-x} per l'uso di \textit{control} e \texttt{M-x} per l'uso
di \textit{alt}. L'uso di \texttt{M-} deriva dal fatto che il secondo tasto
modificatore viene chiamato ``\textit{meta}'' in tutta la documentazione di
\texttt{emacs}, perché questo era il nome che aveva quando il programma è
stato creato.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Operazione} & \textbf{Combinazione di tasti} \\
    \hline
    \hline
    aprire un file  & \texttt{C-x C-f} seguito dal nome del file nel
                      minibuffer (supporta il completamento automatico). \\
%   aaa             &  \\
    salvare un file & \texttt{C-x C-s}.\\
    salvare con nome& \texttt{C-x C-w} seguito dal nome del file nel
                      minibuffer (supporta il completamento automatico). \\
    uscire          & \texttt{C-x C-c}, se ci sono modifiche chiede se
                      salvarle, scartarle o cancellare l'operazione.\\
%   ddsds                &  \\
    annullare       & \texttt{C-\_}, \texttt{C-/} o \texttt{C-x u},
                      ripetendo si torna ulteriormente indietro
                      nell'annullamento. \\
    seleziona       & \texttt{C-spazio} marca l'inizio di una regione e si
                      porta in modalità selezione, poi basta posizionarsi nel
                      punto finale. \\ 
    taglia          & \texttt{C-w} una volta selezionata una regione. \\
    incolla         & \texttt{C-y}.\\
    cancella        & \texttt{C-d} in avanti e il tasto di backspace
                      all'indietro.\\
    ricerca         & \texttt{C-s} seguito dal testo nel minibuffer esegue un
                      ricerca incrementale sul testo specificato, \texttt{C-s}
                      cerca il successivo, \texttt{C-r} cerca il precedente.\\
    help            & \texttt{C-h ?} poi scegliere nella finestra quello che
                      si vuole.\\
    annulla         & (un comando) \texttt{C-g} o tre volte ESC.\\
    \hline
  \end{tabular}
  \caption{I principali comandi di \texttt{emacs}.} 
  \label{tab:emacs_commands}
\end{table}
        
In tab.~\ref{tab:emacs_commands} si è riportata la lista delle principali
operazioni e dei relativi comandi per eseguirle. I comandi elencati in
tab.~\ref{tab:emacs_commands} sono attivi in qualunque modalità si usi
\texttt{emacs}, infatti essendo un editor programmabile \texttt{emacs} può
essere usato in modalità diverse a seconda del tipo di file su cui si sta
lavorando, prevedendo in ciascun caso diverse serie di combinazioni di tasti e
diversi comandi di manipolazione.

Per questo il programma ne mette però a disposizione molti altri sia generici
che specifici per il tipo di file su cui si sta lavorando. Ad esempio
scrivendo questo testo con LaTeX si hanno tutta una serie di comandi per
mettere le parole negli indici, creare le intestazioni delle sezioni o delle
tabelle, creare riferimenti a tabelle e figure presenti, ecc.

In generale poi la combinazione \texttt{M-x} consente di invocare qualunque
funzionalità chiamando per nome la relativa funzione che la realizza. Dato che
l'editor è programmabile anche funzionalità elementari sono realizzate tramite
funzioni, ciascuna delle quali ha un nome, per cui se si vuole eseguire una
correzione ortografica del testo corrente si potrà ad esempio invocare
\texttt{M-x ispell-buffer}.  Molti di questi comandi, ad esempio tutti quelli
che richiedono l'immissione di un nome di file, usano il minibuffer per
ricevere i relativi dati. Il minibuffer viene poi anche utilizzato per
stampare messaggi e avvertimenti.  

Inoltre in certi casi (come quello della specificazione di un file) la
selezione supporta il meccanismo dell'autocompletamento (usando il tasto di
tabulazione), e la capacità, qualora i completamenti siano multipli, di creare
automaticamente una lista di selezione in una nuova finestra. In questo caso
per spostarsi da una finestra all'altra occorrerà usare il comando \texttt{C-x
  o} (che ripetuto ritorna alla precedente), mentre per eliminare tutte le
finestre presenti tranne quella dove è posizionato il cursore si potrà usare
il comando \texttt{C-x 1}.



\subsection{Un editor di base: \texttt{vi}}
\label{sec:vi}

Uno degli editor più popolari, presente fin dagli inizi in tutti i sistemi
Unix, è \index{editor!\texttt{vi}} \texttt{vi}. Purtroppo i perché di questo
nome si sono persi nei meandri del tempo, forse erano due lettere rimaste
libere scelte a caso ...  Questo editor deriva dagli editor di linea (si
chiamano così i primi editor, nati ai tempi delle telescriventi, in cui si
poteva modificare solo una riga alla volta) e ne eredita alcune
caratteristiche. In particolare \texttt{vi} è un editor \textsl{modale}, in
cui cioè sia i comandi che l'effetto di quanto si scrive dipendono dalla
\textsl{modalità di operazioni} in cui il programma si trova al momento.

Questa caratteristica lo rende senz'altro assai poco intuitivo e abbastanza
difficile da usare per il novizio.  Ma i fan(atici) tendono invece a
considerarla una caratteristica utile in quanto (secondo loro) con l'abitudine
renderebbe più veloce le operazioni.  Succede spesso però che al primo impatto
non si riesca neanche ad uscire dall'editor, specie se capita di avere a che
fare con una installazione che non ha attivato l'uso delle frecce.

\begin{figure}[!htb]
\centering
\includegraphics[scale=0.5]{images/vi}
\caption{Schermata di avvio dell'editor \texttt{vi}.}
\label{fig:base_vi_screen}
\end{figure}

Al contrario di \texttt{emacs}, di cui è il principale concorrente,
\texttt{vi} si usa soltanto per manipolare file di testo, e pertanto non
fornisce direttamente nessuna delle funzionalità più evolute di \texttt{emacs}
(come la possibilità di fare debug dei programmi all'interno dell'editor
facendo riferimento diretto al codice su cui si sta lavorando) ma resta
comunque un editor molto potente.

Il principale vantaggio di \texttt{vi} è che essendo molto leggero e diffuso
fin dalle prime versioni di Unix lo si trova installato praticamente su
qualunque sistema e molto spesso è anche l'editor di default.  Inoltre anche
se le funzionalità del programma originale sono veramente minime, esistono
alcune versioni più moderne, come \texttt{vim}, che hanno introdotto una lunga
serie di capacità avanzate, come l'evidenziazione della sintassi. Non è detto
però che quest'ultimo sia sempre disponibile al posto del \texttt{vi} di base
e non è detto che lo sia in una distribuzione di recupero, dato che con le
funzionalità sono aumentate di pari passo anche le dimensioni.

Al solito \texttt{vi} si invoca passando come argomento il nome del file da
modificare, il programma apre il file in una finestra unica (mostrata in
fig.~\ref{fig:base_vi_screen}), dove compare il testo ed in cui ci si muove
con le frecce,\footnote{questo in teoria non è scontato per le versioni più
  elementari, ma quelle installate in tutte le distribuzioni di GNU/Linux se
  non altro supportano nativamente l'uso delle frecce.}  lasciando libera
l'ultima linea, usata per specificare i parametri di alcuni comandi o per
ricevere le informazioni stampate dal programma, che nel caso sono il nome del
file, la sua lunghezza in righe e caratteri e la posizione del cursore sulla
prima colonna della prima riga.

Tutti le operazioni di \texttt{vi} sono eseguite con pressioni di singoli
tasti, ma la possibilità di dare dei comandi al programma dipende dalla
modalità in cui ci si trova. Come accennato infatti \texttt{vi} è un editor
\textsl{modale} e supporta due modalità principali: la modalità
\textsl{comando} e la modalità \textsl{inserimento}, ne esistono poi altre,
come la modalità \textsl{sostituzione} o la modalità \textsl{selezione} di
\texttt{vim}, ma non staremo ad entrare nei dettagli.  In \textsl{modalità
  inserimento} i tasti premuti vengono utilizzati per scrivere il
corrispondente carattere, in \textsl{modalità comando} invece ciascun tasto
viene interpretato ed associato all'esecuzione di una specifica operazione.

Quando si avvia il programma questo si pone sempre in \textsl{modalità
  comando}, e si potranno eseguire le varie operazioni con la pressione del
tasto corrispondente, in questo caso sullo schermo non sarà visualizzato
nulla, se non l'effetto del comando eseguito. Tutti i comandi più complessi,
ad esempio quelli che richiedono la scrittura di una espressione di ricerca o
di un nome di file, devono essere dati dalla riga di comando dell'editor, che
si attiva premendo ``\texttt{:}'', in questo caso il cursore si sposta dal
testo e si pone sulla riga finale, dove si potrà inserire il resto
dell'espressione.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Operazione} & \textbf{Combinazione di tasti} \\
    \hline
    \hline
    aprire un file  & \texttt{:e \textsl{file}}\\
    salvare un file & \texttt{:w}\\
    salvare con nome& \texttt{:w \textsl{nomefile}}\\
    uscire          & \texttt{:q}, ma se ci sono modifiche non esce; nel caso
                      \texttt{:wq} le salva  mentre \texttt{:q!} le scarta \\
    annullare       & \texttt{u} solo sull'ultima modifica\\
    seleziona       & \texttt{v}, e poi ci si sposta con i tasti di freccia, ma
                      è una estensione esclusiva di \texttt{vim} (modalità
                      \textit{visual})\\ 
    taglia          & \texttt{d}, per la selezione fatta con la
                      modalità \textit{visual} di \texttt{vim}\\ 
    copia           & \texttt{y}, per la selezione fatta con la
                      modalità \textit{visual} di \texttt{vim}\\
    incolla         & \texttt{p} inserisce l'ultimo oggetto cancellato.\\
    cancella        & \texttt{d} seguito da una altra lettera che specifica
                      cosa cancellare; \texttt{x} cancella un carattere\\
    ricerca         & \texttt{/} seguito da un testo o una espressione regolare\\
    annulla         & ESC annulla un comando\\
    \hline
  \end{tabular}
  \caption{Come svolgere le principali operazioni con \texttt{vi}.} 
  \label{tab:vi_operations_summary}
\end{table}

In tab.~\ref{tab:vi_operations_summary} si è riportata una lista delle
principali operazioni relative ai compiti più comuni, associate ai rispettivi
comandi.  Si tenga presente però che questi possono essere attivati solo in
modalità comando, se ci si è posti in modalità inserimento (o sostituzione)
prima bisognerà uscirne con ESC. 

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Comando} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{h} & spostamento a sinistra di un carattere.\\
    \texttt{j} & spostamento in basso di una riga.\\
    \texttt{k} & spostamento in alto di una riga.\\
    \texttt{l} & spostamento a destra di un carattere.\\
    \texttt{w} & spostamento in avanti di una parola.\\
    \texttt{b} & spostamento indietro di una parola.\\
    \texttt{0} & spostamento ad inizio riga.\\
    \texttt{\$}& spostamento a fine riga.\\
    \texttt{f} & spostamento prima della prima occorrenza del carattere
                 seguente.\\ 
    \texttt{t} & spostamento dopo la prima occorrenza del carattere
                 seguente.\\ 
    \hline
    \texttt{i} & va in modalità inserimento alla posizione corrente.\\
    \texttt{a} & va in modalità inserimento al carattere seguente.\\
    \texttt{A} & va in modalità inserimento a fine riga.\\
    \texttt{I} & va in modalità inserimento a inizio riga.\\
    \texttt{o} & inserisci una riga sotto quella corrente.\\
    \texttt{O} & inserisci una riga sopra quella corrente.\\
    \hline
    \texttt{x} & cancella il carattere alla posizione corrente.\\
    \texttt{X} & cancella il carattere precedente la posizione corrente.\\
    \texttt{s} & cancella il carattere corrente e vai in inserimento.\\
    \texttt{S} & cancella la riga corrente e vai in inserimento.\\
    \texttt{d\textsl{X}} & seguito da un qualunque comando di spostamento
                           \texttt{\textsl{X}} cancella dalla posizione
                           corrente a quella dello spostamento.\\ 
    \texttt{dd}& cancella la riga corrente.\\
    \texttt{D} & cancella fino a fine riga.\\
    \texttt{c\textsl{X}} & come \texttt{d\textsl{X}} ma si pone in
                           inserimento eseguita la cancellazione.\\
    \texttt{cc}& cancella la riga corrente e si pone in inserimento.\\
    \texttt{C} & cancella fino a fine riga e si pone in inserimento.\\
    \hline
    \texttt{r} & rimpiazza il carattere alla posizione corrente.\\
    \texttt{R} & sovrascrivi a partire dalla posizione corrente.\\
    \hline
    \texttt{y\textsl{X}} & seguito da un qualunque comando di spostamento
                           \texttt{\textsl{X}} copia dalla posizione corrente
                           a quella dello spostamento.\\ 
    \texttt{yy} o \texttt{Y}& copia l'intera riga corrente.\\
    \texttt{p} & incolla quanto cancellato dopo la posizione corrente.\\
    \texttt{P} & incolla quanto cancellato prima della posizione corrente.\\
    \hline
    \texttt{/\textsl{regex}} & cerca l'espressione regolare
                               \texttt{\textsl{regex}} in avanti.\\  
    \texttt{?\textsl{regex}} & cerca l'espressione regolare
                               \texttt{\textsl{regex}} indietro.\\  
    \texttt{n} & cerca la corrispondenza successiva.\\
    \texttt{N} & cerca la corrispondenza precedente.\\
    \hline
    \texttt{v} & entra in modalità \textsl{selezione} (\textit{visual}) per 
                 effettuare una selezione di testo (solo su \texttt{vim}).\\ 
    \texttt{d} & cancella quanto selezionato (con la modalità
                 \textsl{selezione} di \texttt{vim}).\\ 
    \texttt{y} & copia quanto selezionato (con la modalità \textsl{selezione}
                 di \texttt{vim}).\\
    \hline
    \texttt{.} & ripete l'ultimo comando.\\
    \texttt{u} & annulla l'ultimo comando (con \texttt{vim} può essere
                 ripetuto).\\
    \hline
  \end{tabular}
  \caption{I principali tasti di comando diretti di \texttt{vi}.} 
  \label{tab:vi_commands}
\end{table}

La pressione dei tasti corrispondenti ai relativi comandi consente di cambiare
modalità; ad esempio premendo ``\texttt{i}'' si passa in modalità inserimento,
e si può iniziare a scrivere in corrispondenza del cursore. Ma ci sono altri
comandi che permettono di entrare in modalità inserimento, come ``\texttt{a}''
che vi entra ma portandosi al carattere seguente o ``\texttt{A}'' che invece
va a fine riga ed anche ``\texttt{o}'' che lo fa andando a capo creando una
nuova riga. Se ne è riportato un sommario nella seconda sezione di
tab.~\ref{tab:vi_commands}. 

È allora abbastanza frequente che un utente alle prime armi, una volta aperto
un file con \texttt{vi}, tenti di scriverci e non veda nulla finché, premuto
uno di questi tasti, non si porta in modalità inserimento.  Il problema in
genere è che una volta entrati in modalità inserimento l'unico modo per
uscirne è quello di premere il tasto di \textit{escape} (ESC); non sapendolo
ci si troverà bloccati ed incapaci di uscire dal programma. In questo caso le
versioni più recenti di \texttt{vim} sono più amichevoli, e reagiscono anche
ad altre combinazioni di tasti, come \texttt{C-c}, dando delle indicazioni, ma
con le versioni più elementari di \texttt{vi} non si ha nessun avviso e si
resta completamente bloccati.

Una modalità simile a quella di inserimento è quella di \textsl{sostituzione},
in cui si entra premendo ``\texttt{R}'', in questo modo di nuovo tutti tasti
assumeranno il loro valore letterale, ma quanto si scrive, invece di essere
inserito in corrispondenza al cursore, spostando il testo già presente,
sovrascriverà quest'ultimo.  Anche da questa modalità si può uscire premendo
il tasto di \textit{escape} (ESC).

Come accennato \texttt{vi} supporta, essendo nato in un epoca in cui le
tastiere non avevano i tasti freccia, lo spostamento nel file con i tasti
``\texttt{h}'', ``\texttt{j}'', ``\texttt{k}'' e ``\texttt{l}'' che effettuano
rispettivamente lo spostamento a sinistra, basso, alto e destra.  Un'altra
caratteristica dell'editor è che qualunque comando dato in modalità comando
può essere moltiplicato se lo si fa precedere da un numero, per cui per
abbassarsi di 10 righe si potrà scrivere qualcosa tipo \texttt{10j}. Nella
prima sezione di tab.~\ref{tab:vi_commands} si è riportato un sommario dei
principali tasti usati come comandi di spostamento.

Si può poi effettuare una ricerca sul testo con l'uso del tasto ``\texttt{/}''
per le ricerche in avanti e con ``\texttt{?}'' per le ricerche indietro,
esattamente come per \texttt{less} e \texttt{more} che in effetti riprendono
la sintassi da \texttt{vi}. Come per i due comandi citati la ricerca viene
eseguita considerando la stringa da cercare una espressione regolare, diventa
così possibile eseguire anche ricerche molto complesse.

Una delle caratteristiche che può lasciare più interdetti con \texttt{vi} è
che non esiste il classico \textsl{taglia e incolla} in cui si seleziona una
sezione qualunque del file, a meno che non usiate \texttt{vim}, che implementa
questa funzionalità definendo una modalità \textsl{selezione} (o
\textit{visual}) in cui si entra con il comando ``\texttt{v}''. % Questa
%modalità si applica ad intere righe se attivata con ``\texttt{v}'' e ad una
%colonna se attivata con \texttt{C-v}.

La sezione selezionata può cancellare con ``\texttt{d}'', ma è possibile
cancellare caratteri singoli (con ``\texttt{x}'' per quello corrente, con
``\texttt{X}'' il precedente), parole (con \texttt{dw}) e righe (con
\texttt{dd}), ed usare i moltiplicatori illustrati in precedenza per
cancellazioni multiple. In generale il concetto è quello di far seguire a
``\texttt{d}'' uno dei comandi di spostamento (quelli della prima parte di
tab.~\ref{tab:vi_commands}), e verrà effettuata la cancellazione dal cursore
fino a quel punto.  Si sono riassunti i vari comandi di cancellazione nella
terza sezione di tab.~\ref{tab:vi_commands}.

Il testo cancellato viene memorizzato in un buffer interno e lo si può poi
incollare (anche più volte se si usano i moltiplicatori) con il tasto
``\texttt{p}'' dopo la posizione corrente o prima con ``\texttt{P}''. Si sono
riassunti i vari comandi di cancellazione nella terza sezione di
tab.~\ref{tab:vi_commands}. Se può invece copiare una sezione di testo senza
cancellarla con ``\texttt{y}''. Anche in questo caso potrà usare la modalità
\textit{visual} per selezionarla, copiare parole con \texttt{yw}, righe con
\texttt{yy} ed in generale usare gli operatori di spostamento in maniera
analoga a quanto si fa con ``\texttt{d}''.

L'apertura di nuovi file deve essere fatta sulla riga di comando, e si esegue
con \texttt{:e}, altri comandi che si possono utilizzare sono \texttt{:w} che
salva il file e \texttt{:x} che salva ed esce, ed è equivalente al normale
comando di uscita con salvataggio che è \texttt{:wq}; l'uscita scartando le
modifiche invece si può forzare con \texttt{:q!}, per questi due comandi
esistono anche delle versioni da dare in modalità normale e cioè
rispettivamente \texttt{ZZ} e \texttt{ZQ}.


\begin{table}[!htbp]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Comando} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{:h}& apre l'\textit{help on line}.\\
    \texttt{:N}& passa al file successivo.\\
    \texttt{:q}& esce (se non ci sono modifiche). \\
    \texttt{:q!} o \texttt{ZQ}& esce scartando le modifiche.\\
    \texttt{:x}  o \texttt{ZZ} o \texttt{:wq}& esce scrivendo le modifiche. \\
    \texttt{:e \textsl{file}}& carica il file \texttt{\textsl{file}}.\\
    \texttt{:e}& rilegge il file da disco.\\
    \texttt{:e!}& rilegge il file da disco, scartando eventuali modifiche.\\
    \texttt{:r \textsl{file}}& include il file \texttt{\textsl{file}} alla
    posizione corrente.\\
    \texttt{:w \textsl{file}}& scrive sul file \texttt{\textsl{file}}.\\
    \texttt{:w!} & salva il file anche se in modalità \textit{readonly} (si
    deve essere proprietari del file).\\
    \texttt{:! \textsl{cmd}} & esegue il comando \texttt{\textsl{cmd}}.\\
    \texttt{:s/\textsl{ric}/\textsl{sub}/} & esegue la sostituzione, con la
    stessa sintassi di \texttt{sed} (vedi
    sez.~\ref{sec:cmd_regular_expression}).\\
    \hline
  \end{tabular}
  \caption{Le principali operazioni nella riga di comando di \texttt{vi}.} 
  \label{tab:vi_command_line}
\end{table}


Un'altra caratteristica interessante della linea di comando di \texttt{vi} è
che è possibile dare dei comandi di shell senza uscire dall'editor; una volta
entrati sulla linea di comando del programma infatti si può usare il carattere
``\texttt{!}'' come \textit{shell escape}, si potrà cioè usare una sintassi
del tipo ``\texttt{:!ls}'' per ottenere la lista dei file su una schermata di
servizio, da cui si potrà uscire, tornando alla modifica del file, premendo
invio.

Un'altra funzionalità presente sulla linea di comando di \texttt{vi} è quella
di sostituzione, attivabile con \texttt{:s}; questa funzionalità ha la stessa
sintassi delle espressioni di sostituzione usate da \texttt{sed}, potremo cioè
effettuare la sostituzione della stringa ``\texttt{\textsl{ric}}'' con la
stringa ``\texttt{\textsl{sost}}'' utilizzando il comando
``\texttt{:s/\textsl{ric}/\textsl{sost}/g}'', ma come per le ricerche, potremo
anche usare le espressioni regolari, ottenendo tutte le funzionalità che si
sono descritte per \texttt{sed} in sez.~\ref{sec:cmd_regular_expression}.

Infine un elenco dei principali comandi può essere ottenuto con la
documentazione interna, accessibile con ``\texttt{:h}''. Si è riportato in
tab.~\ref{tab:vi_command_line} l'elenco dei principali comandi che richiedono
l'uso della riga di comando di \texttt{vi} (quelli che iniziano con
``\texttt{:}'') mentre la tabella riassuntiva di quelli diretti è in
tab.~\ref{tab:vi_commands}, che è stata suddivisa in diverse sezioni relative
ai comandi delle varie tipologie di operazioni.


\subsection{Altri editor}
\label{sec:other_edit}

Chiudiamo questa sezione con una breve panoramica sugli altri principali
editor disponibili. Il primo di questi, un editor leggero e potente, è
\index{editor!\texttt{joe}} \texttt{joe}, gli affezionati del DOS noteranno
che usa la sintassi di \textit{wordstar}, un word processor testuale di
quell'epoca. Offre tutte le normali funzionalità di un editor di testi e ha un
help in linea per i vari comandi che si attiva con \texttt{C-k h}, che lo
rende piuttosto facile da usare. Inoltre l'editor si può usare in modalità di
emulazione usando le sintassi di altri editor; ad esempio invocandolo come
\texttt{jmacs} userà la sintassi di \texttt{emacs}.

\begin{figure}[!htb]
\centering
\includegraphics[scale=0.5]{images/joe}
\caption{Schermata di avvio dell'editor \texttt{joe}.}
\label{fig:base_joe_screen}
\end{figure}
        
Al solito \texttt{joe} si invoca passando come argomento un nome di file, che
viene aperto e visualizzato nella finestra principale, mostrata in
fig.~\ref{fig:base_joe_screen}. La finestra presenta una riga di stato in
testa, contenente i soliti dati (file, posizione, lunghezza ed il suggerimento
per ottenere la schermata di aiuto), seguita dalla sezione principale in cui
compare il testo del file ed in cui ci si muove con le frecce, l'ultima linea
viene usata per mostrare i messaggi e per dare i comandi o ricevere le
informazioni, e scompare quando non è necessaria.

In tab.~\ref{tab:joe_commands} sono riportati i principali comandi per le
funzionalità di base. Anche in questo caso l'editor non supporta il concetto
classico del \textsl{taglia e incolla} in cui si rimuove il testo col taglia e
poi lo si incolla altrove, ed usa invece l'approccio dello \textsl{sposta o
  copia} in cui prima si seleziona una sezione di testo e poi si specifica se
spostarla oppure copiarla altrove.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Operazione} & \textbf{Combinazione di tasti} \\
    \hline
    \hline
    aprire un file  & \texttt{C-k e} seguito dal nome del file.\\
    salvare un file & \texttt{C-k x}.\\
    salvare con nome& \texttt{C-k d} seguito dal nome del file.\\
    uscire          & \texttt{C-k x} esce e salva, \texttt{C-c} esce e se ci
                      sono modifiche chiede d eventualmente scarta.\\
%   ddsds                &  \\
    annullare       & \texttt{C-\_}, mentre con \verb|C-^| si ripete l'ultima
                      operazione.\\
    seleziona       & \texttt{C-k b} all'inizio e poi spostarsi con le frecce
                      e dare \texttt{C-k k} alla fine.\\  
    sposta          & \texttt{C-k m} muove la regione selezionata sulla
                      posizione attuale.\\ 
    copia           & \texttt{C-k c} copia la regione selezionata sulla
                      posizione corrente.\\
    cancella        & \texttt{C-k y} in avanti e \textit{backspace} indietro.\\
    ricerca         & \texttt{C-k f} seguito da un testo esegue la prima
                      ricerca, \texttt{C-L} cerca l'occorrenza successiva.\\
    annulla         & (un comando) \texttt{C-c}.\\
    \hline
  \end{tabular}
  \caption{I principali comandi di \texttt{joe}.} 
  \label{tab:joe_commands}
\end{table}

Un altro editor per la \textit{console} è \index{editor!\texttt{jed}}
\texttt{jed}, scritto come reimplementazione di \texttt{emacs} in C, che è
molto più leggero di quest'ultimo (ma anche molto meno potente).  Supporta
anch'esso però un linguaggio di programmazione interno, ed è pertanto in grado
di fornire parecchie funzionalità avanzate, e utilizzare diverse sintassi per
i comandi a seconda del tipo di file.  Fornisce anche un'ampia capacità di
evidenziazione della sintassi in \textit{console} che con \texttt{emacs} è
divenuta disponibile solo a partire dalla versione 21.

\begin{figure}[!htb]
  \centering \includegraphics[scale=0.5]{images/jed}
\caption{Schermata di avvio dell'editor \texttt{jed}.}
\label{fig:base_jed_screen}
\end{figure}

Essendo \texttt{jed} in sostanza un clone di \texttt{emacs} non staremo a
ripeterne i comandi principali, che sono gli stessi di
tab.~\ref{tab:emacs_commands}, anche la composizione della finestra (una cui
immagine è mostrata in fig.~\ref{fig:base_jed_screen}) è analoga a quella di
\texttt{emacs} per cui basta rifarsi a quanto detto in precedenza; il
vantaggio di \texttt{jed} è che l'utilizzo del menu è molto più intuitivo e
avviene direttamente in modalità semigrafica anziché all'interno di finestre
secondarie.

Un altro editor abbastanza diffuso è \index{editor!\texttt{pico}}
\texttt{pico}; questo è derivato da \texttt{pine}, un vecchio client per
leggere la posta elettronica in \textit{console}, separando da esso l'editor
interno usato per scrivere le email.  Data la maggiore utilizzabilità rispetto
a \texttt{vi} esso si è diffuso parecchio, il problema è che siccome
\texttt{pine} non è software libero, non lo è neanche \texttt{pico}. Per
questo motivo è stato realizzato un clone completamente libero chiamato
\index{editor!\texttt{nano}} \texttt{nano} identico dal punto di vista dei
comandi principali, ma molto più leggero, anche più di \texttt{vi}, tanto da
essere usato nei dischi di avvio di Debian per la shell di emergenza, e con
qualche capacità in più.

\begin{figure}[!htb]
\centering
\includegraphics[scale=0.5]{images/nano}
\caption{Schermata di avvio dell'editor \texttt{nano}.}
\label{fig:base_nano_screen}
\end{figure}

Il programma si invoca al solito passando come argomento il nome del file da
modificare, che viene aperto nella finestra mostrata in
fig.~\ref{fig:base_nano_screen}, in cui si ha una riga di stato all'inizio, e
due righe di aiuto in basso che riportano i comandi disponibili al momento,
sulle quali vengono fatte pure le eventuali richieste di immissione o
richieste scelte sulle azioni da compiere. 
 
Un altro editor testuale che ha conosciuto un certo successo è
\texttt{mcedit}. Anche questo è un sottoinsieme di un altro programma,
\texttt{mc} (nome che sta per \textit{Midnight Commander}), un file manager
semigrafico utilizzabile in \textit{console} che nasce come clone del
\textit{Norton Commander}. Anche questo è un editor che mantiene nella prima
riga un riassunto dei comandi principali, per cui non staremo a descriverne i
dettagli.

Tutti gli editor citati finora sono in grado di funzionare in modalità
testuale su un terminale o dalla \textit{console}, per completezza è opportuno
citare che esistono tutta una serie di editor \textsl{grafici} come quelli
inseriti in \textit{Gnome} (\texttt{gedit}) e \textit{KDE} (\texttt{kate}) che
non sono spiegati qui in quanto l'interfaccia grafica è in grado di dare
accesso alle funzionalità base con i soliti menu.
        
Fra gli editor grafici vale la pena segnalare uno dei più evoluti:
\texttt{nedit} che dispone di un linguaggio di programmazione interno che ne
permette una grande espandibilità ed è dotato di moltissime funzionalità
(forse il più vicino ad \texttt{emacs}); per questo è uno degli editor più
potenti, pur restando anche facile da usare.  Esistono infine anche versioni
grafiche di alcuni degli editor precedenti (come \texttt{gvim} per
\texttt{vi}), mentre come già accennato sia \texttt{emacs} che \texttt{xemacs}
usati dall'interfaccia grafica mettono a disposizione menu e utilizzo del
mouse.



\section{Altri comandi di utilità}
\label{sec:cmd_others}

Dopo aver trattato i comandi che operano sui file, in questa sezione faremo
una panoramica sugli altri principali comandi disponibili, attinenti
funzionalità del sistema che finora non sono state prese in considerazione,
come i comandi per eseguire manipolazioni avanzate sulla redirezione, quelli
per la documentazione, quelli per gestire orologio e tempi di sistema, quelli
per visualizzare le informazioni relative agli utenti ed al sistema e quelli
che consentono di ottenere una serie di altre informazioni di vario tipo ad
uso prevalentemente diagnostico.


\subsection{I comandi di ausilio per la redirezione}
\label{sec:cmd_redirection}

Nonostante la grande flessibilità degli operatori di redirezione della shell,
esistono situazioni in cui il loro uso non è sufficiente a fornire le
funzionalità necessarie, per questo esistono dei comandi che permettono di
estendere l'uso della redirezione.

Ad esempio uno dei fraintendimenti più comuni riguardo l'uso della
concatenazione dei comandi è quello in cui si pensa di usare la \textit{pipe}
per passare come \textsl{argomenti} ad un comando successivo l'output di un
comando precedente. Questo non è ovviamente possibile perché l'uso di una
\textit{pipe} consente solo di passare lo \textit{standard output} di un
comando sullo \textit{standard input} del successivo, e non ha nulla a che
fare con gli argomenti di quest'ultimo.

Si ricordi infatti che gli argomenti provengono dall'analisi che fa la shell
dalla linea di comando, spezzandola in parole, e che vengono passati in fase
di messa in esecuzione di un programma, operazione che non ha nulla a che fare
con la lettura, che avviene sempre a cura del comando stesso, dei dati
presenti sullo \textit{standard input}.

È però possibile fornire questa funzionalità con l'uso del comando
\index{comando!\texttt{xargs}} \texttt{xargs}, il cui compito è replicare il
comportamento della shell, che legge la linea di comando e ne estrae gli
argomenti per poi passarli al comando che invoca. Il comando cioè effettua la
lettura dello \textit{standard input} e ne ricava una lista di argomenti da
passare ad un successivo comando, in questo modo diventa possibile ricevere
gli argomenti dall'output di un comando precedente tramite una \textit{pipe}.

Il comando \texttt{xargs} prende come primo argomento il nome del comando da
eseguire e come ulteriori argomenti le eventuali opzioni o argomenti iniziali
da passare allo stesso. Il comando viene poi eseguito passandogli una lista di
ulteriori argomenti, ottenuta dalla scansione dello \textit{standard input}
utilizzando gli spazi e gli a capo come separatori.  È possibile proteggere la
presenza di spazi all'interno degli argomenti come si fa con la shell, usando
le virgolette o la barra trasversa. Se non si specifica nessun comando da
eseguire, di default viene usato \texttt{echo}.

In questo modo se si ha una lista di file (o si è in grado di generarla)
diventa possibile applicare a ciascun file della lista un comando qualunque
usando semplicemente \texttt{cat} e \texttt{xargs}. Se cioè si vogliono
cancellare tutti i file contenuti nel file \texttt{lista}, si potrà usare un
comando del tipo:
\begin{Example}
cat lista | xargs rm -f
\end{Example}
se invece li si vogliono copiare in una directory si potrà usare:
\begin{Example}
cat lista | xargs cp -t dir 
\end{Example}
ovviamente nel far questo occorrerà stare molto attenti, è sempre
consigliabile infatti, quando si usa \texttt{xargs}, lanciare il comando senza
argomenti per verificare che non si stiano facendo degli errori.

Il comando permette di impostare, con l'opzione \texttt{-E} una stringa da
usare come marcatore per la fine del file, in modo da ignorare tutto quanto
sarà ottenuto dopo. Con l'opzione \texttt{-t} permette inoltre di stampare a
video il comando che verrà eseguito, e con \texttt{-p} di richiedere conferma
dell'esecuzione sul terminale. Infine l'opzione \texttt{-0} richiede che
quanto letto sullo \textit{standard input} sia interpretato come stringhe
terminate da uno zero (il carattere NUL), così da poter interpretare
letteralmente i vari caratteri, in modo da non dover trattare in maniera
speciale spazi, virgolette, ecc.

Questo consente di risolvere i problemi che si hanno quando si deve operare
con \texttt{find} su dei file che hanno degli spazi o altri caratteri
interpretati dalla shell nel nome; combinando l'opzione \texttt{-0} di
\texttt{xargs} con l'opzione \texttt{-print0} di \texttt{find} si potranno
trattare anche i nomi più complicati.

Si tenga presente che i due esempi precedenti per l'uso di \texttt{xargs}
funzionano regolarmente perché i comandi utilizzati accettano come argomenti
una lista di file, quando però si vogliono fare delle operazioni più complesse
(ad esempio rinominare dei file sulla base di una elaborazione del loro nome)
ci si trova di fronte al problema che programmi come \texttt{mv} si aspettano
di avere due argomenti e non una lista.

In questo caso ci viene incontro una delle caratteristiche più interessanti di
\texttt{xargs}, che è quella di poter eseguire invocazioni multiple dello
stesso comando. Con l'opzione \texttt{-n} infatti si può indicare il numero
massimo di argomenti (sempre presi dalla lista ottenuta dalla scansione dello
\textit{standard input}) da passare a ciascuna invocazione, se si ricevono più
argomenti i successivi saranno utilizzati per un'altra invocazione.

Se invece gli argomenti già sono suddivisi per linee, si può usare l'opzione
\texttt{-L} che consente di indicare quante linee dello \textit{standard
  input} utilizzare per ciascuna invocazione del comando.  Così se volessimo
rinominare tutti i file \texttt{.tex} di questo testo aggiungendo un
\texttt{\_new} al rispettivo nome potremmo usare qualcosa del
tipo:\footnote{si lascia come esercizio l'interpretazione dell'espressione
  regolare usata per \texttt{sed}.}
\begin{Example}
ls *.tex | sed -r -e 's/(.*)(.tex)/\1\2 \1_new\2/g' | xargs -L1 mv
\end{Example}

Si sono riassunte le principali opzioni di \texttt{xargs} in
tab.~\ref{tab:cmd_xargs_options}; l'elenco completo delle opzioni ed una
descrizione dettagliata del comando si possono trovare come sempre consultando
la pagina di manuale, accessibile con \texttt{man xargs}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-a \textsl{file}}& indica di leggere gli argomenti dal file
                \texttt{\textsl{file}} anziché dallo \textit{standard input}.\\ 
    \texttt{-E \textsl{str}}& indica la stringa \texttt{\textsl{str}} da 
                 considerare come fine del file, così da scartare tutto quello
                 che segue, sostituisce nello standard POSIX l'opzione
                 \texttt{-e} (tutt'ora presente) che ha lo stesso effetto.\\
    \texttt{-n \textsl{N}}& usa al massimo \texttt{\textsl{N}} argomenti per 
                 ciascuna invocazione del comando.\\
    \texttt{-L \textsl{N}}& usa un massimo di \texttt{\textsl{N}} linee come
                 argomenti per ciascuna invocazione del comando.\\
    \texttt{-p}& richiede conferma sul terminale prima di eseguire un
                 comando.\\ 
    \texttt{-t}& aumenta la prolissità del comando.\\
    \texttt{-r}& non esegue nessun comando se non si ha niente in ingresso.\\
    \texttt{-0}& richiede la terminazione dei singoli argomenti con un
                 carattere nullo al posto dei normali spazi e disabilita
                 l'interpretazione dei caratteri speciali.\\
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{xargs}.}
  \label{tab:cmd_xargs_options}
\end{table}

Un secondo comando di ausilio per la redirezione è
\index{comando!\texttt{tee}} \texttt{tee}.  Il suo scopo principale è quello
di permettere di salvare su un file un risultato intermedio all'interno di una
catena di redirezioni. In tal caso infatti l'uscita di un comando viene
inviata sulla \textit{pipe} e letta dal comando successivo, perdendo così la
possibilità di esaminarla direttamente. 

L'idea che sta alla base di \texttt{tee}, indicata dal suo stesso nome, è
quella di creare una sorta di percorso a ``T'' nel flusso di dati della catena
di redirezioni, in cui questi da una parte proseguono verso il comando
successivo e dall'altra vengono salvati su un file. Questo significa che la
maniera più comune di utilizzare \texttt{tee} sarà qualcosa nella forma:
\begin{Example}
cmd1 | tee result | cmd2 
\end{Example}
che consente di scrivere il risultato di \texttt{cmd1} sul file
\texttt{result} ed al contempo inviarlo in \textit{pipe} a \texttt{cmd2} per
una ulteriore elaborazione.

Alternativamente si può usare il comando in coda ad una catena di redirezioni
per salvare il risultato ed allo stesso tempo visualizzarlo sullo
schermo. L'uso di \texttt{tee} infatti permette di effettuare una sorta di
redirezione in \textit{background}, in cui quello che il comando legge dallo
\textit{standard input} viene scritto sia sul file passato come argomento che
sullo \textit{standard output}.  Il comando, come nella normale redirezione
dello \textit{standard output}, è anche in grado di eseguire la scrittura del
file specificato in \textit{append}, se invocato con l'opzione \texttt{-a}. Al
solito per tutti i dettagli di funzionamento e l'elenco completo delle opzioni
si consulti la pagina di manuale.

Un ultimo comando usato come ausilio per la redirezione è
\index{comando!\texttt{yes}} \texttt{yes}, che ha il semplice compito (se
invocato senza argomenti) di scrivere continuamente sullo \textit{standard
  input} una serie di ``\texttt{y}''. Anche in questo caso l'utilità di fare
un comando per un compito così specifico diventa evidente solo considerando la
capacità della shell di concatenare i comandi, per cui si può usare
\texttt{yes} per \textsl{pilotare} automaticamente lo \textit{standard input}
di un comando che richiede conferme (come potrebbe essere \texttt{rm -i}). Il
comando non ha nessuna opzione specifica e prende come argomento opzionale una
stringa, che se indicata viene scritta sullo \textit{standard input} al posto
di ``\texttt{y}''.


\subsection{I comandi per la documentazione}
\label{sec:documentazione}

Benché talvolta possa risultare difficile trovare informazioni aggiornate
sulle funzionalità più esoteriche, una delle caratteristiche di un sistema
GNU/Linux è quella di essere fornito di una quantità impressionante di
documentazione, tanto che una delle risposte più frequenti alle domande di
chiarimento è RTFM, sigla che sta, a seconda dell'umore del momento, per
\textit{Read The Fine Manual} o \textit{Read The Fucking Manual}.

Come accennato in sez.~\ref{sec:cmd_general} ciascun comando di norma supporta
di suo una opzione \texttt{-{}-help} (spesso abbreviata in \texttt{-h}) che
permette di visualizzarne brevemente la sintassi. Dato che questa informazione
è in genere solo uno stringato riassunto delle opzioni disponibili, la fonte
primaria delle informazioni relative ai comandi è nelle \textsl{pagine di
  manuale}, fin qui abbondantemente citate, gestite con il comando
\index{comando!\texttt{man}} \texttt{man}.

Tutti i comandi di sistema prevedono infatti una pagina di manuale cui si
accede semplicemente con la sintassi \texttt{man \textsl{comando}}. In
particolare poi gli sviluppatori di Debian hanno come impegno preciso quello
di fornire per ogni pacchetto la relativa documentazione. Ma le pagine di
manuale non fanno riferimento solo ai comandi, il sistema infatti ha origine
fin dai primi Unix e prevede la documentazione di tutto il sistema.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Sezione} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{(1)}& programmi eseguibili o comandi di shell.\\
     \texttt{(2)}& \textit{system call} (funzioni fornite dal kernel).\\ 
     \texttt{(3)}& funzioni di libreria.\\
     \texttt{(4)}& documentazione sui file di dispositivo.\\ 
     \texttt{(5)}& formati dei file di configurazione.\\
     \texttt{(6)}& giochi.\\
     \texttt{(7)}& varie (convenzioni, informazioni generiche su argomenti).\\
     \texttt{(8)}& comandi di amministrazione.\\
    \hline
  \end{tabular}
  \caption{Sezioni delle pagine di manuale.}
  \label{tab:cmd_man_sections}
\end{table}

Per questo le pagine di manuale sono divise in sezioni, il cui numero è quello
che compare fra parentesi nella prima riga di ciascuna pagina dopo il nome del
comando in maiuscolo. Ciascuna sezione contiene la documentazione relativa ad
un certo argomento, secondo la classificazione riportata in
tab.~\ref{tab:cmd_man_sections}, in cui però si sono messe solo le sezioni
``\textsl{classiche}''. Ci possono infatti essere altre sezioni specifiche
installate insieme ad alcuni pacchetti, ad esempio quelle della documentazione
del linguaggio \textit{Perl}, che non prenderemo in considerazione.

Con \texttt{man} si richiama la pagina di manuale, dove in genere si trova una
documentazione esaustiva e dettagliata della sintassi e delle opzioni di un
comando o del formato e del significato delle direttive di un file di
configurazione. Il comando supporta una serie di opzioni che ne modificano il
comportamento (riassunte in tab.~\ref{tab:cmd_man_options}) ed altre che
consentono di controllare la formattazione per inviare l'output su stampante,
al solito tutti i dettagli si trovano nella sua pagina di manuale, alla quale,
come per gli altri comandi, si accede con \texttt{man man}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-a} & mostra tutte le pagine di manuale che corrispondono.\\
    \texttt{-k \textsl{str}} & cerca le pagine di manuale che hanno la stringa
                  \texttt{\textsl{str}} nella descrizione (equivalente ad
                  \texttt{apropos}).\\
    \texttt{-f \textsl{cmd}} & elenca le pagine corrispondenti a \texttt{cmd}
                  (equivalente a \texttt{whatis}).\\
    \texttt{-w} & mostra dove è la pagina di manuale, non il suo contenuto.\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{man}.}
  \label{tab:cmd_man_options}
\end{table}

Si tenga presente che il comando \texttt{man} richiama la pagina relativa al
nome che si è passato come argomento, cercando in sequenza nelle varie sezioni
e restituendo la prima che trova.  Si tenga presente che la sequenza non è
detto sia quella di tab.~\ref{tab:cmd_man_sections}, essa infatti si imposta
nella configurazione del sistema di gestione delle pagine di manuale, come
vedremo a breve.  

Per questo se esistono più versioni della stessa pagina in sezioni diverse
(come ad esempio per il comando \texttt{passwd} e per il file
\texttt{/etc/passwd}) verrà mostrata solo la prima, a meno di non aver
specificato l'opzione \texttt{-a}. Se si vuole accedere alla seconda si dovrà
richiamarla esplicitamente indicando la sezione come primo argomento, con un
qualcosa del tipo \texttt{man 5 passwd}.

Il sistema delle pagine di manuale permette comunque di verificare se esistono
più pagine associate ad uno stesso nome con il comando
\index{comando!\texttt{whatis}} \texttt{whatis}, che stampa l'elenco delle
pagine ad esso corrispondenti, così ad esempio avremo:
\begin{Console}
piccardi@anarres:~$ \textbf{whatis passwd}
passwd (1)           - change user password
passwd (5)           - The password file
\end{Console}
%$

Un'altra funzionalità utile del sistema delle pagine di manuale è fornita dal
comando \index{comando!\texttt{apropos}} \texttt{apropos} che permette di
effettuare la ricerca della parola passata come argomento fra le descrizioni
brevi dei comandi che compaiono nella intestazione delle pagine di manuale
(quelle appena mostrate anche nell'output di \texttt{whatis}) per cui potremo
eseguire la ricerca:
\begin{Console}
piccardi@anarres:~$ \textbf{apropos "user password"}
chage (1)            - change user password expiry information
passwd (1)           - change user password
\end{Console}
%$
e si noti come si siano usati i doppi apici per effettuare una ricerca su una
stringa contenente uno spazio, dato che altrimenti si sarebbero passate due
stringhe al comando.

Come accennato il comando \texttt{man} supporta la possibilità di generare
documentazione stampabile. Questo avviene perché in realtà le pagine di
manuale non sono scritte direttamente nel formato in cui le vediamo su video,
ma in uno speciale linguaggio di formattazione, chiamato \textit{troff}, che
permette la creazione di sezioni, indici, ecc. Per questo il testo mostrato
sul terminale, è solo uno fra i vari formati di uscita disponibili.

Tutte le volte che si richiama il comando \texttt{man} per visualizzare una
nuova pagina di manuale il comando dovrà recuperare uno di questi file
generando un testo in formato opportuno per la visualizzazione. Per evitare di
ripetere il procedimento della generazione ad una successiva invocazione tutti
questi file vengono salvati, usualmente sotto \texttt{/var/cache/man/}, in una
directory \texttt{cat\textsl{N}}, dove \texttt{\textsl{N}} corrisponde alla
sezione cui appartiene la pagina, così da poterli recuperare velocemente.

Un secondo aspetto del sistema delle pagine di manuale è quello
dell'indicizzazione dei contenuti usata dai comandi \texttt{whatis} e
\texttt{apropos}; questa infatti non è diretta (come si può verificare tutte
le volte che si installa un nuovo pacchetto e non lo si trova nei risultati di
detti comandi), ma viene effettuata normalmente tramite il programma
\index{comando!\texttt{mandb}} \texttt{mandb}, che costruisce gli opportuni
file con gli indici usati dai precedenti.

In genere il programma viene invocato periodicamente nelle operazioni
giornaliere eseguite da \texttt{cron} (vedi sez.~\ref{sec:crontab}), ma lo si
può anche invocare direttamente; le opzioni principali sono \texttt{-c} che
gli fa ricreare tutti gli indici da zero (il default è aggiornare quelli
esistenti) e \texttt{-p} che non fa eseguire la ripulitura degli indici dei
dati della pagine non più presenti; per la descrizione completa delle altre
opzioni ed i dettagli sul comando al solito si faccia riferimento alla sua
pagina di manuale.

Per stabilire in quale directory si trovano gli originali delle pagine, in che
ordine cercarle, dove devono essere memorizzate le pagine riformattate per la
visualizzazione, dove mantenere gli indici delle pagine presenti e delle
parole su cui effettuare le ricerche, il sistema di gestione delle \textit{man
  pages} usa il file di configurazione
\index{configurazione!\texttt{/etc/manpath.config}}
\texttt{/etc/manpath.config}.

Il primo aspetto della configurazione è quello della definizione delle
directory in cui si trovano le pagine di manuale; come per gli eseguibili
infatti anch'esse possono essere installate in diverse sezioni dell'albero. Si
pensi infatti al caso in cui si siano installate diverse versioni di uno
stesso pacchetto, ad esempio una versione più recente a mano sotto
\texttt{/usr/local}, in tal caso le pagine di manuale saranno sotto
\texttt{/usr/local/man} ed il sistema deve essere in grado di vederle, ed in
un certo ordine rispetto alle altre. Una lista di tutte queste directory si
può stampare con il comando \index{comando!\texttt{manpath}} \texttt{manpath},
ed in genere si otterrà qualcosa del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{manpath}
/usr/local/man:/usr/local/share/man:/usr/share/man
\end{Console}
%$
a meno di non aver definito in maniera diretta la variabile di ambiente
\index{variabili!di~ambiente!\texttt{MANPATH}} \texttt{MANPATH} (nel qual caso
sarà semplicemente stampato il suo valore) che permette di soprassedere il
valore preimpostato dal sistema.

La configurazione delle directory in cui cercare le pagine di manuale è una di
quelle impostazioni mantenute in \texttt{manpath.config}. La direttiva
\texttt{MANDATORY\_MANPATH} serve per indicare tutte le directory che si vuole
siano sempre aggiunte (se esistono) alla lista di quelle in cui si cercano le
pagine di manuale; la direttiva prende come argomento il pathname alla
directory contenente gli originali, e deve essere ripetuta per tutte le
directory che si vuole siano aggiunte alla lista.

La direttiva \texttt{MANPATH\_MAP} indica invece la corrispondenza fra le
directory dei comandi e le relative pagine di manuale; serve per aggiornare
dinamicamente la lista delle directory in cui cercare le pagine di manuale
sulla base delle directory presenti nel \texttt{PATH} (vedi
sez.~\ref{sec:shell_sintax}) dell'utente. La direttiva richiede due
argomenti; il primo indica una directory contenente i comandi, il secondo la
directory delle corrispondenti pagine di manuale. Se la prima compare nel
\texttt{PATH} dell'utente la seconda è aggiunta al \texttt{MANPATH} in maniera
implicita.

Infine la direttiva \texttt{MANDB\_MAP} serve ad indicare a \texttt{mandb}
dove devono essere messi i file degli indici, e dove devono essere create le
pagine temporanee. Un estratto del file \texttt{manpath.config}, così come
installato su una Debian Sid, è il seguente:
\begin{FileExample}[label=manpath.config]
MANDATORY_MANPATH                       /usr/man
MANDATORY_MANPATH                       /usr/share/man
MANDATORY_MANPATH                       /usr/local/man
...
MANPATH_MAP     /bin                    /usr/share/man
MANPATH_MAP     /usr/bin                /usr/share/man
MANPATH_MAP     /sbin                   /usr/share/man
MANPATH_MAP     /usr/sbin               /usr/share/man
MANPATH_MAP     /usr/local/bin          /usr/local/man
...
MANDB_MAP       /usr/man                /var/cache/man/fsstnd
MANDB_MAP       /usr/share/man          /var/cache/man
MANDB_MAP       /usr/local/man          /var/cache/man/oldlocal
MANDB_MAP       /usr/local/share/man    /var/cache/man/local
MANDB_MAP       /usr/X11R6/man          /var/cache/man/X11R6
MANDB_MAP       /opt/man                /var/cache/man/opt
...
SECTION         1 n l 8 3 2 3posix 3pm 3perl 5 4 9 6 7
\end{FileExample}

L'ultima direttiva, \texttt{SECTION}, indica l'ordine di ricerca delle pagine
di manuale nelle varie sezioni, si noti come nell'esempio appena citato ci
siano altre sezioni oltre a quelle classiche illustrate in
tab.~\ref{tab:cmd_man_sections}.

Oltre alla consultazione delle pagine di manuale, una seconda fonte di
informazioni e documentazione è costituita dal sistema di \textit{help on
  line} fornito dal comando \index{comando!\texttt{info}} \texttt{info} e
dalle cosiddette \textit{info pages}. In questo caso si tratta di una forma
alternativa di strutturazione delle informazioni che usa un formato diverso e
che aggiunge, rispetto alle pagine di manuale, delle caratteristiche più
avanzate e molto comode come la possibilità di navigare usando link ad altre
pagine, una organizzazione gerarchica strutturata ad albero con nodi e
sezioni, la possibilità di consultare indici, ecc.\footnote{tanto che queste
  informazioni vengono utilizzate anche da altri programmi, come i vari
  sistemi di \textit{help on line} degli ambienti grafici.}  Grazie a questa
struttura \texttt{info} permette anche di accedere a documenti più complessi
di una semplice pagina di manuale, e vi si trovano una grande quantità di
manuali di grandissima importanza, come documentazione sui sistemi di
sviluppo, sui linguaggi, sulle librerie, ecc.

Date le sue caratteristiche evolute \textit{info} è il formato raccomandato
dal progetto GNU, che lo considera alternativo rispetto alle pagine di
manuale.  Molti però continuano ad utilizzare quest'ultime per cui alla fine i
due sistemi si trovano a convivere. In genere il contenuto delle pagine di
manuale è direttamente accessibile anche con il comando \texttt{info comando},
ma usualmente è disponibile anche un'informazione di livello più alto; ad
esempio la documentazione dettagliata dei comandi più complessi della
\textit{Unix toolbox}, che comprende anche le spiegazioni generali sulla
architettura scelta, viene mantenuta nelle pagine \textit{info} del relativo
pacchetto, accessibili con \texttt{info coreutils}.

Se ci si limita a richiamare il comando \texttt{info} ci verrà mostrata la
radice del sistema dove sono elencati tutti i documenti installati, e sarà
possibile iniziare la navigazione spostandosi con le frecce, seguire i link
premendo invio, tornare al livello precedente premendo ``\texttt{u}'', passare
al nodo successivo con ``\texttt{n}'', tornare al nodo precedente con
``\texttt{p}'', andare all'indice con ``\texttt{i}'', effettuare una ricerca
con ``\texttt{/}'', ed infine visualizzare i vari comandi disponibili con
``\texttt{?}''. La potenza del sistema è che, come per le pagine di manuale, i
testi vengono generalmente scritti in un apposito linguaggio di formattazione,
per cui la versione testuale è solo una delle possibili forme di
visualizzazione, e si può facilmente accedere alla stessa documentazione
anche dall'interfaccia grafica con gli opportuni programmi di consultazione.

Si tenga presente poi che spesso i pacchetti dei singoli programmi vengono
distribuiti con la documentazione prodotta direttamente dagli autori, che di
norma, seguendo le indicazioni del \textit{Filesystem Hierarchy Standard},
viene installata in una directory \texttt{/usr/share/doc/nomeprogramma}. A
questa documentazione specifica poi si aggiunge il patrimonio degli HOWTO, una
serie di documenti sul \textsl{come fare} a riguardo di un certo argomento,
disponibili in diversi formati (dal testo puro, all'HTML, al PDF).  Questi
sono stati raccolti dal \textit{Linux Documentation Project}
(\href{http://www.tldp.org}{\texttt{http://www.tldp.org}}), e di norma vengono
installati dalle varie distribuzioni nella directory
\texttt{/usr/share/doc/HOWTO/}.

%%
%% ### OBSOLETE BEGIN ###
%% Materiale obsoleto su usenet, TLDP, Pluto, oggi poco usati
%%
\ifx\obsoletesection\undefined

\relax
\else
Infine quando non si riescono a trovare informazioni nel sistema si può
ricorrere direttamente ad Internet. Una delle risorse più usate è costituita
appunto dal \textit{Linux Documentation Project}, sul cui sito si trovano le
versioni aggiornate di molti HOWTO.  Qui sono disponibili anche delle guide,
veri e propri libri su vari argomenti come l'amministrazione di sistema, il
kernel, ecc.  La traduzione italiana di questi documenti si può trovare sul
sito del PLUTO (gruppo storico di utenti Linux italiani) nella sezione
dedicata all'\textit{Italian Linux Documentation Project}, accessibile
all'indirizzo \href{http://ildp.pluto.it/}{\texttt{http://ildp.pluto.it/}}.

Una grande quantità di informazioni, e l'aiuto di altri utenti, può essere
trovato sui gruppi di discussione di \textit{usenet}, una rete internazionale
di distribuzione di notizie in cui chiunque (usando il relativo client) può
lasciare messaggi e ricevere risposte (la filosofia di funzionamento del
sistema è ripresa da quella delle bacheche pubbliche delle università). 

In tal caso il proprio provider deve aver fornito un accesso ad un
\textit{news server} che riceve i gruppi dedicati alle discussioni su
Linux. Tanto per cambiare, dato che anche questo servizio è nato su Unix, i
gruppi di discussioni sono organizzati per temi, e strutturati ad albero in
una gerarchia per cui si va da un tema più generale (\texttt{comp} per i
computer) a temi sempre più specifici: \texttt{comp.os} per i sistemi
operativi, \texttt{comp.lang} per i linguaggi di programmazione, ecc.

Quelli che riguardano Linux sono quelli si trovano nella gerarchia
internazionale (in lingua inglese) sotto \texttt{comp.os.linux}, mentre nella
gerarchia italiana si trovano sotto \texttt{it.comp.os.linux}. In tal caso è
comunque opportuno leggere in anticipo le FAQ (\textit{Frequently Asked
  Question}) che raccolgono una serie di risposte alla domande più ricorrenti,
onde evitare di ripetere domande banali a cui è stata data risposta
innumerevoli volte, che non sarebbero accolte molto amichevolmente.
%%
%% ### OBSOLETE END ###
%% Materiale obsoleto su usenet, TLDP, Pluto, oggi poco usati
%%
\fi

Infine l'utilizzo dei motori di ricerca è un ottimo sistema per recuperare le
informazioni pubblicate su Internet, ed alcuni di essi forniscono anche un
accesso specifico per ricerche su questo argomento. Fra queste troverete le
versioni pubblicate degli HOWTO (anche se queste vengono spesso distribuite
come documentazione nel sistema, non è detto che siano complete o aggiornate)
ma anche altre risorse come le annotazioni ed i log, le istruzioni lasciate in
innumerevoli pagine web e gli archivi delle liste di discussione dei vari
progetti in cui qualcuno può aver già avuto il vostro problema e trovato una
risposta.


\subsection{I comandi per la gestione dei tempi}
\label{sec:cmd_time}

Prima di accennare ai principali comandi per la gestione di tempo e date in
GNU/Linux occorre una breve introduzione sulla gestione del tempo nei sistemi
Unix. Storicamente i sistemi unix-like hanno sempre mantenuto due distinti
tipi di tempo all'interno del sistema: essi sono rispettivamente chiamati
\textit{calendar time} e \textit{process time}, secondo le seguenti
definizioni:
\begin{description}
\item[\textit{calendar time}] o \textsl{tempo di calendario}. È il numero di
  secondi dalla mezzanotte del primo gennaio 1970, in \textsl{tempo universale
    coordinato} (o UTC), data che viene usualmente indicata con
  \texttt{00:00:00 Jan, 1 1970 (UTC)} e chiamata ``\textit{the Epoch}''.
  Questo tempo viene spesso chiamato anche GMT (\textit{Greenwich Mean Time})
  dato che l'UTC corrisponde all'ora locale di Greenwich.\footnote{in realtà
    con GMT si fa alle volte riferimento al tempo solare misurato
    dall'osservatorio di Greenwich, che è leggermente diverso, per i dettagli
    si consulti \url{http://en.wikipedia.org/wiki/UTC}}. È il tempo su cui
  viene mantenuto l'orologio del kernel, e viene usato ad esempio per indicare
  le date di modifica dei file o quelle di avvio dei processi.
\item[\textit{process time}] o \textsl{tempo di processore}. È il tempo usato
  internamente dal kernel per le sue temporizzazioni. In genere è legato alle
  interruzioni del timer hardware, e viene impiegato per tutti i calcoli dello
  scheduler, è pertanto il tempo in cui viene misurato il tempo di esecuzione
  dei processi.
\end{description}

In genere il tempo a cui si fa riferimento è sempre il \textit{calendar time},
il \textit{process time} viene usato soltanto dai comandi che riportano le
proprietà specifiche dei processi (come \texttt{ps} o \texttt{top}) relative
ai tempi di esecuzione degli stessi. Oltre a questi due, già trattati in
sez.~\ref{sec:struct_proc_property}, l'unico altro comando comune che usa il
\textit{process time} è \index{comando!\texttt{time}} \texttt{time}, che
prende come argomento una riga di comando da eseguire, e stampa a video, alla
terminazione dell'esecuzione di quest'ultima, tre valori di tempo espressi in
\textit{process time}, che sono il tempo totale impiegato per l'esecuzione del
programma (con la sigla \texttt{real}), il tempo passato nell'esecuzione di
codice in user space (con la sigla \texttt{user}), ed il tempo passato
nell'esecuzione di codice dentro il kernel, cioè all'interno delle
\textit{system call} invocate dal processo (con la sigla \texttt{sys}), ad
esempio:
\begin{Console}
piccardi@hain:~$ \textbf{time ls}
CVS  README  corso  internet-server  ldap  lucidi  samba
 
real    0m0.030s
user    0m0.000s
sys     0m0.010s
\end{Console}
%$
e si noti come il tempo \textsl{reale} è sempre maggiore degli altri due in
quanto tiene conto anche del tempo in cui il processo è stato in stato di
\textit{sleep} in attesa di I/O. 

Il comando prende varie opzioni, le principali delle quali sono \texttt{-o}
che permette di specificare un file su cui scrivere i risultati al posto dello
\textit{standard output}, e \texttt{-f} che permette di specificare un formato
per i tempi.  La descrizione completa del comando (comprese le stringhe usate
per l'opzione \texttt{-f}) si trova al solito nella pagina di manuale.

Tutti gli altri comandi relativi ai tempi hanno a che fare con la gestione del
\textit{calendar time}. Qui si aggiungono ulteriori complicazioni; la prima è
che esistono due orologi, quello di sistema, usato dal kernel per tutte le sue
operazioni, ed aggiornato via software dal kernel stesso, e l'orologio
hardware che funziona in maniera del tutto indipendente e che rimane in
funzione anche quando la macchina è spenta.\footnote{è l'orologio che si trova
  sulla scheda madre, ed è alimentato dalla batteria che si trova su di essa.}
Di solito il kernel legge l'orologio hardware all'avvio, per impostare il
valore iniziale dell'orologio di sistema, e poi non lo considera più.

La seconda complicazione è che il kernel non conosce assolutamente i fusi
orari; per lui il tempo è assoluto, e fa sempre riferimento al tempo standard
universale (l'UTC appunto). Tutta la gestione dei fusi orari è demandata alle
applicazioni in user space che, tutte le volte che leggono un tempo, devono
essere in grado di convertirlo nell'ora locale, il tutto è fatto attraverso
delle opportune funzioni di libreria, che permettono di eseguire il compito in
maniera trasparente, torneremo sull'argomento con maggiori dettagli in
sez.~\ref{sec:localization}.

Se ci si pensa questa è la scelta più logica: non solo si evita di inserire
una serie di informazioni complesse all'interno del kernel, ma facendo così i
tempi di sistema sono sempre coerenti, e non dipendono dal fuso orario in cui
ci si trova, nel senso che i file modificati un'ora fa risulteranno sempre con
l'ora giusta qualunque cambiamento sia stato fatto nel fuso orario.  Purtroppo
altri sistemi operativi usano l'ora locale per l'orologio di sistema che
coincide con l'orologio hardware, con tutti i problemi che questo comporta
quando si deve cambiare fuso orario (con file che possono anche risultare
essere stati creati nel futuro), e soprattutto di incompatibilità dei tempi in
caso di dual boot.

Il principale comando che permette di leggere ed impostare l'orologio di
sistema è \index{comando!\texttt{date}} \texttt{date}. Se usato senza
argomenti questo si limita a stampare data ed ora corrente nel formato
standard:
\begin{Console}
piccardi@hain:~$ \textbf{date}
Fri Sep 19 12:45:42 CEST 2003
\end{Console}
%$
il comando prende come argomento o il tempo da impostare (operazione
privilegiata che può eseguire solo l'amministratore) o un formato di stampa
per il tempo che modifica l'output del comando facendogli stampare solo le
parti di data volute.

Se si vuole impostare la data questa deve essere specificata con una stringa
nella forma \texttt{MMDDhhmm[[CC]YY][.ss]}, dove i termini fra parentesi
quadra sono opzionali. Con \texttt{MM} si indica il mese (in numero), con
\texttt{DD} il giorno, con \texttt{hh} l'ora, con \texttt{mm} il minuto,
mentre l'anno si indica o con le cifre finali \texttt{YY} o per intero con
tanto di secoli come \texttt{CCYY}, infine i secondi \texttt{ss} devono essere
preceduti da un punto; ad esempio si può provare ad impostare l'orologio con:
\begin{Console}
piccardi@hain:~$ \textbf{date 09191854}
date: cannot set date: Operation not permitted
Fri Sep 19 18:54:00 CEST 2003
\end{Console}
%$
e l'operazione fallisce, dato che non si è l'amministratore, ma il tempo che
si voleva impostare viene comunque stampato a video. 

Se invece l'argomento che si passa inizia con un ``\texttt{+}'' esso viene
interpretato come una stringa di formattazione per il risultato del comando.
La stringa usa il carattere ``\texttt{\%}'' per indicare una direttiva di
formattazione che verrà sostituita dall'opportuno valore, tutti gli altri
caratteri resteranno immutati. Le principali direttive sono riportate in tab.
\ref{tab:cmd_date_directive}, l'elenco completo è nella pagina di manuale.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|c|p{10cm}|}
    \hline
    \textbf{Direttiva} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{\%\%}& il carattere \texttt{\%}.\\
     \texttt{\%a} & il nome del giorno della settimana abbreviato, secondo la
                    localizzazione.\\ 
     \texttt{\%A} & il nome del giorno della settimana completo, secondo la
                    localizzazione.\\
     \texttt{\%b} & il nome del mese abbreviato, secondo la localizzazione.\\
     \texttt{\%B} & il nome del mese completo, secondo la localizzazione.\\
     \texttt{\%c} & data e orario, secondo la localizzazione.\\
     \texttt{\%d} & giorno del mese, nella forma \texttt{(01..31)}.\\
     \texttt{\%D} & data, nella forma \texttt{(mm/dd/yy)}.\\
     \texttt{\%H} & ora del giorno, nella forma \texttt{( 0..23)}.\\
     \texttt{\%I} & ora del giorno, nella forma \texttt{( 1..12)}.\\
     \texttt{\%m} & mese, nella forma \texttt{(01..12)}.\\
     \texttt{\%M} & minuto, nella forma \texttt{(00..59)}.\\
     \texttt{\%r} & orario nella forma \texttt{(hh:mm:ss [AP]M)} su 12 ore.\\
     \texttt{\%T} & orario nella forma \texttt{(hh:mm:ss)} su 24 ore.\\
     \texttt{\%S}& numero di secondi.\\
     \texttt{\%w}& giorno della settimana, nella forma \texttt{(0..6)} a
                   partire dalla domenica.\\
     \texttt{\%x}& data nella rappresentazione secondo
                   la localizzazione.\\
     \texttt{\%y}& anno abbreviato alle ultime due cifre.\\
     \texttt{\%Y}& anno completo.\\
     \texttt{\%Z}& nome convenzionale del fuso orario.\\
    \hline
  \end{tabular}
  \caption{Direttive di formattazione per il comando \texttt{date}.}
  \label{tab:cmd_date_directive}
\end{table}

Il comando prende inoltre varie opzioni, le principali delle quali sono
\texttt{-d} che permette di specificare una data da stampare al posto del
tempo corrente, e \texttt{-s} che permette, con lo stesso formato, di
specificare l'impostazione dell'orologio di sistema. L'utilità di queste due
opzioni è che la stringa che prendono come parametro può essere nelle forme
più varie, e non solo riconosce tutti i formati standard che si ottengono con
le direttive di tab.~\ref{tab:cmd_date_directive}, ma anche descrizioni
verbali (solo in inglese, però) come \texttt{8 day ago}, o \texttt{1 month}.
La descrizione di queste stringhe può essere trovata solo nelle pagine info
del comando, accessibili con \texttt{info date}, dove si trova anche la
trattazione completa di tutte le funzionalità.

Il secondo comando che riguarda la gestione del tempo è
\index{comando!\texttt{hwclock}} \texttt{hwclock}, che permette di impostare
l'orologio hardware. Il comando non prende argomenti, e lo si utilizza
attraverso le opzioni. Se non si specifica nessuna opzione il comando si
limita leggere il valore dell'orologio hardware e a stamparlo sullo
\textit{standard output}, con un risultato del tipo:
\begin{Console}
root@hain:~# \textbf{hwclock}
Tue Sep 23 15:36:58 2003  -0.763201 seconds
\end{Console}
(risultato che si ottiene anche con l'opzione \texttt{-r} o
\texttt{-{}-show}).

Il comando poi permette di impostare l'orologio hardware con l'opzione
\texttt{-{}-set}, cui deve seguire un \texttt{-{}-date} che specifichi la data
da usare nel formato con cui la si specifica anche per \texttt{date}. Si può
però usare l'opzione \texttt{-w} (o \texttt{-{}-systohc}) per impostare l'ora
direttamente al tempo segnato dall'orologio di sistema. Viceversa l'opzione
\texttt{-s} (o \texttt{-{}-hctosys}) imposta l'orologio di sistema al tempo di
quello hardware.

Infine un altro comando molto utilizzato nella gestione dell'orologio di
sistema è \index{comando!\texttt{ntpdate}} \texttt{ntpdate} che consente di
sincronizzare l'ora con un server NTP (\textit{Network Time Protocol})
esterno. In genere infatti l'orologio di sistema di una macchina non è molto
preciso, e tende ad andare avanti o restare indietro a seconda delle
condizioni di carico; anche l'orologio hardware, pur essendo fornito da un
quarzo interno, risente delle variazioni di temperatura e di tensione sulla
piastra madre. Per questo motivo si possono avere delle derive significative
nei tempi.

Il servizio NTP è un servizio di rete (che tratteremo in
sez.~\ref{sec:net_NTP}) a cui ci si può rivolgere per poter \textsl{rimettere}
l'orologio di una macchina, il comando \texttt{ntpdate} effettua una richiesta
ad un server NTP, il cui indirizzo viene passato come
argomento,\footnote{diamo per scontata la conoscenza del significato di
  indirizzo, l'argomento viene affrontato nei dettagli in
  sez.~\ref{sec:net_intro} e sez.~\ref{sec:net_name_resolution}; il comando
  accetta sia indirizzi IP in forma numerica, che nomi a dominio in forma
  simbolica, come quello dell'esempio.} e sincronizza l'orologio di sistema
con l'orario fornito dal server.  Il modo più comune per invocare il programma
è:
\begin{Console}
root@hain:~# \textbf{ntpdate pool.ntp.org}
28 Dec 9:51:58 ntpdate[2199]: adjust time server 44.4.14.88 offset 0.006230 sec
\end{Console}

Si può invocare il comando con l'opzione \texttt{-q} per fargli semplicemente
eseguire una richiesta senza aggiornare l'ora, e l'opzione \texttt{-v} per
fargli stampare più informazioni, le restanti opzioni, ed i dettagli relativi
al funzionamento del programma, sono al solito riportati nella pagina di
manuale.

Si tenga presente che se il programma rivela una differenza di tempo maggiore
0.5 secondi effettua una sincronizzazione immediata, e si avrà pertanto uno
\textsl{scalino} nella scala dei tempi, mentre se la differenza è inferiore
provvede ad accelerare (o decelerare) l'orologio di sistema finché la
differenza non sia stata compensata.\footnote{i dettagli sulle funzioni con
  cui viene effettuato l'aggiornamento vanno al di là degli scopi di questo
  testo, si può trovare una trattazione dell'argomento in sez.~8.4.3 di
  \cite{GaPiL}.}


\subsection{I comandi per le informazioni sugli utenti e il sistema}
\label{sec:user_sys_info}

Tratteremo in questa sezione una serie di comandi utilizzabili per ottenere
informazioni sulle identità degli utenti, i gruppi cui appartengono, gli
accessi al sistema e altre caratteristiche generali del sistema. 
Un primo comando, che permette di verificare con quale utente ci si è
collegati al sistema, è \index{comando!\texttt{whoami}} \texttt{whoami}, che
stampa il valore del proprio \textit{username} con qualcosa del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{whoami}
piccardi
\end{Console}
%$
e se può sembrare superfluo verificare con quale utente ci si è collegati
(cosa che di norma ci viene ricordata anche dal prompt della shell) si pensi
invece a quanto può essere utile nel caso di uno script di shell che debba
eseguire compiti diversi in base all'utente che lo esegue.

Per verificare di quali gruppi fa parte un utente si può usare invece il
comando \index{comando!\texttt{groups}} \texttt{groups}. Questo, se invocato
senza nessun argomento, stampa l'elenco dei nomi dei gruppi a cui si
appartiene, ad esempio:
\begin{Console}
piccardi@anarres:~$ \textbf{groups}
piccardi voice cdrom audio video plugdev lpadmin fuse scanner saned vboxusers
\end{Console}
%$
se invece si specifica come argomento un nome utente, il comando stampa la
lista di gruppi cui appartiene l'utente indicato. Sia \texttt{groups} che
\texttt{whoami} non hanno opzioni se non quelle standard GNU viste in
sez.~\ref{sec:cmd_general}.

Il comando più generale è però \index{comando!\texttt{id}} \texttt{id}, che
consente di ottenere i valori di tutti gli identificativi associati ad un
utente. Il comando stampa i valori di utente e relativi gruppi sia in forma
letterale che numerica, e permette di scegliere se stampare quelli reali o
quelli effettivi (si ricordi quanto visto in sez.~\ref{sec:struct_multiuser});
un esempio del suo utilizzo è:
\begin{Console}
piccardi@anarres:~$ \textbf{id}
uid=1002(piccardi) gid=1002(piccardi) groups=22(voice),24(cdrom),29(audio),44(vi
deo),46(plugdev),117(lpadmin),119(fuse),120(scanner),122(saned),124(vboxusers),1
002(piccardi)
\end{Console}
%$
in cui, invocato senza argomenti, stampa tutti gli identificativi associati
all'utente corrente.\footnote{ad essere pignoli, si tratta in realtà degli
  identificativi associati al processo che esegue \texttt{id}, che prevedono
  sia l'\textit{user ID} che i vari \textit{group ID}, nel caso specifico
  quelli del gruppo \textit{real}.}

Oltre alla possibilità di passare un argomento che specifica l'utente di cui
si vogliono ottenere gli identificativi, il comando prende molte opzioni che
permettono di indicare nei dettagli quali informazioni si vogliono stampare ed
in che formato; con \texttt{-u} si può chiedere di mostrare solo
l'\textit{user ID}, con \texttt{-g} il \textit{group ID}, è inoltre possibile
chiedere la visualizzazione dei identificativi del gruppo \textit{real}
(quelli dell'utente che ha lanciato il processo) invece degli
\textit{effective} (quelli per conto di cui gira il processo, mostrati di
default) con l'opzione \texttt{-r}. Al solito si può fare riferimento alla
pagina di manuale, accessibile con \texttt{man id}, per la documentazione
completa.

Oltre ai dati relativi agli identificativi associati ai singoli utenti, sulla
cui gestione amministrativa torneremo in
sez.~\ref{sec:users_groups_management}, il sistema mantiene anche una serie di
informazioni sulle loro attività, che possono essere richieste con altrettanti
comandi. In particolare tutte le volte che un utente si collega al sistema e
avvia un terminale l'evento viene registrato in uno specifico
formato\footnote{per i dettagli si può consultare sez.~6.4.2 di \cite{GaPiL}.}
nei file \texttt{/var/log/wtmp} e \texttt{/var/run/utmp} (il primo contiene le
informazioni storiche, il secondo quelle correnti) insieme ad altre
informazioni relative sia alla modalità in cui avviene l'accesso che ad altri
eventi di sistema. In particolare vengono registrati in questi file tutti i
riavvii ed in generale tutti i cambiamenti di \textit{runlevel} (vedi
sez.~\ref{sec:runlevel_control}) che sono stati eseguiti.

I dati vengono registrati in questi file in forma binaria, ma possono essere
consultati con l'ausilio di alcuni comandi dedicati, che consentono di
ottenere informazioni sugli accessi degli utenti ed anche sulle attività
svolte nel sistema. Ad esempio l'elenco degli utenti attualmente collegati si
può ottenere con l'uso del comando \index{comando!\texttt{users}}
\texttt{users} che stampa a video una semplice lista degli stessi, da usare ad
esempio in uno script che debba inviare avvisi, con qualcosa del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{users}
root piccardi 
\end{Console}
%$

Una lista più dettagliata può essere ottenuta con il comando
\index{comando!\texttt{who}} \texttt{who}, che stampa l'elenco in forma di
tabella, riportando per ciascun utente collegato al sistema il relativo
\textit{username} seguito dal terminale su cui questo è attivo, dall'ora in
cui è avvenuto l'accesso e dall'eventuale macchina remota o dal
\textit{display} dell'interfaccia grafica (vedi sez.~\ref{sec:X_client}) da
cui questo è avvenuto, cioè qualcosa del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{who}
piccardi tty1         2008-03-26 00:02
piccardi pts/0        2008-03-27 12:45 (192.168.0.3)
piccardi pts/1        2008-03-23 12:07 (:0.0)
\end{Console}
%$
che mostra tre sessioni dello stesso utente, una effettuata da una console
locale, una da una macchina remota ed una dall'interfaccia grafica.

Il comando supporta molte opzioni (al solito per i dettagli si consulti la
pagina di manuale), volte a stampare le varie informazioni disponibili, ma in
generale lo si usa senza argomenti per avere la lista degli utenti come
illustrato. Se gli si passa un argomento questo verrà considerato il nome del
file da cui leggere le informazioni,\footnote{il comando usa
  \texttt{/var/run/utmp} che contiene le informazioni correnti, ma gli si può
  passare come argomento \texttt{/var/log/wtmp} per fargli leggere quelle
  archiviate.} mentre con due argomenti stampa soltanto la voce relativa
all'utente che lo ha lanciato.

In quest'ultimo caso si tende ad usarlo nella forma discorsiva \texttt{who am
  i}, che ricorda il precedente \texttt{whoami}, ma oltre al risultato, che
presenta il nome dell'utente insieme al terminale e alle altre informazioni
mostrate nel precedente esempio,\footnote{qualora si voglia stampare il nome
  utente è possibile usare il comando \texttt{logname}, ma anche questo fa
  riferimento all'utente collegato.} \index{comando!\texttt{logname}} è
diverso anche il significato, \texttt{whoami} infatti riporta il nome
dell'utente associato all'\textit{user ID} del processo corrente e dà sempre
un risultato, mentre \texttt{who am i} fa riferimento all'utente
effettivamente collegato, per cui se usato all'interno di uno script eseguito
in modalità non interattiva (ad esempio lanciato con \texttt{cron}, vedi
sez.~\ref{sec:crontab}) non darà nessun risultato.

Come alternativa a \texttt{who} esiste anche il comando
\index{comando!\texttt{w}} \texttt{w}, che esegue lo stesso compito ma stampa
delle informazioni più dettagliate. In particolare il comando stampa sempre
una riga introduttiva, analoga a quella mostrata anche da \texttt{top}, che
riporta ora, tempo trascorso dall'ultimo riavvio (l'\textit{uptime}), numero
di utenti connessi e carico medio della macchina, cui segue la lista degli
utenti in cui, oltre alle informazioni già riportate da \texttt{who} ci sono
pure i dati relativi al tempo di CPU usato dall'utente ed il comando corrente;
si avrà cioè:
\begin{Console}
piccardi@anarres:~$ \textbf{w}
 14:49:36 up 4 days,  2:45,  3 users,  load average: 0.00, 0.01, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
piccardi tty1     -                Wed03   35:38   0.76s  0.73s -bash
piccardi pts/0    192.168.0.3      12:45    0.00s  0.49s  0.01s w
piccardi pts/1    :0.0             Sun12    3days  1:00   1:00  top
\end{Console}
%$

Infine oltre alle informazioni riguardo gli utenti e le attività di sistema
correnti, si possono consultare quelle archiviate riguardo gli accessi passati
con il comando \index{comando!\texttt{last}} \texttt{last}.  In genere il
periodo coperto è quello dell'ultimo mese, in quanto, come vedremo in
sez.~\ref{sec:logrotate}, il file \texttt{/var/log/wtmp} da cui vengono
ricavate le informazioni viene \textsl{ruotato} mensilmente.

Il comando stampa una lista degli ultimi accessi avvenuti in forma analoga a
\texttt{who}, ma riporta oltre alla data di ingresso anche quella di uscita e
la durata di ciascuna sessione, vengono stampate inoltre informazioni
generali, come le date del riavvio del sistema; si avrà cioè qualcosa del
tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{last}
piccardi pts/0        192.168.0.3      Thu Mar 27 12:45   still logged in   
piccardi pts/0        192.168.0.3      Wed Mar 26 22:22 - 01:29  (03:07)    
piccardi pts/0        192.168.0.3      Wed Mar 26 12:11 - 16:20  (04:09)    
piccardi tty1                          Wed Mar 26 00:02   still logged in   
...
reboot   system boot  2.6.17-12-powerp Sun Mar 23 12:05 - 15:03 (4+02:57)   
...
wtmp begins Fri Mar  2 17:17:47 2007
\end{Console}
%$

Il comando prevede varie opzioni, come \texttt{-n} seguita da un numero, che
consente di indicare quante righe stampare o \texttt{-t} seguita da una data,
che stampa lo stato a quella data; si può così vedere chi era collegato
osservando le righe con \texttt{still logged in}. Al solito per una
descrizione completa si faccia riferimento alla pagina di manuale.

Infine oltre \texttt{last} altri comandi che vengono in genere utilizzati per
ottenere informazioni sugli accessi sono \index{comando!\texttt{lastb}}
\texttt{lastb}, che stampa l'elenco dei tentativi falliti, e
\index{comando!\texttt{uptime}} \texttt{uptime}, che è quello che produce la
riga iniziale con i dati relativi a utenti collegati e tempo dall'ultimo avvio
che viene usata come prima riga da \texttt{top} e \texttt{w}. Per tutti i
dettagli come sempre si consultino le pagine di manuale.

Un ultimo comando che permette di ottenere informazioni sul sistema è
\index{comando!\texttt{uname}} \texttt{uname}, che stampa una serie di
informazioni generiche. Se invocato senza argomenti il comando si limita a
stampare il nome del proprio kernel (vale a dire \texttt{Linux}), che non è
una informazione particolarmente significativa. Più interessanti sono le
informazioni relative all'architettura hardware o al tipo di processore
stampabili rispettivamente con le opzioni \texttt{-m} e \texttt{-p}, mentre
con \texttt{-n} si può stampare il nome assegnato alla macchina stessa (vedi
anche sez.~\ref{sec:net_hosts}) e con \texttt{-a} tutte le informazioni
disponibili, ottenendo qualcosa del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{uname -a}
Linux anarres 2.6.32-5-686 #1 SMP Mon Jan 16 16:04:25 UTC 2012 i686 GNU/Linux
\end{Console}
%$

L'uso più frequente del comando però è quello in cui esso viene invocato con
l'opzione \texttt{-r} per ottenere soltanto la versione del kernel corrente
(nel caso \texttt{2.6.32-5-686}), informazione che viene usata spesso nella
gestione dei moduli dello stesso (torneremo su questo argomento in
sez.~\ref{sec:kernel}). Al solito l'elenco completo delle opzioni e tutti i
dettagli del comando si possono ottenere consultando la relativa pagina di
manuale.


\subsection{I comandi per le informazioni diagnostiche}
\label{sec:diagnostic_command}

Tratteremo in quest'ultima sezione una serie di comandi che consentono di
ottenere informazioni dettagliate di varia natura relativamente ai processi e
alle caratteristiche del sistema, riuniti per la loro caratteristica comune di
essere utilizzati principalmente a scopi diagnostici. L'uso di questi comandi
è in genere molto specialistico e la loro comprensione completa richiede una
conoscenza approfondita del sistema, in particolare i concetti relativi alle
reti fanno riferimento ad argomenti che saranno trattati solo a partire dal
cap.~\ref{cha:networks_base}. Per questo ne daremo solo una descrizione
superficiale, da tenere come riferimento per una lettura più approfondita
delle rispettive pagine di manuale, che possa però risultare utile per fornire
una panoramica su come utilizzarli per effettuare la diagnosi di problemi e
malfunzionamenti del sistema.

Il primo comando che prendiamo in considerazione è
\index{comando!\texttt{dmesg}} \texttt{dmesg}, che invocato semplicemente
consente di stampare a video il contenuto del \textsl{buffer
  circolare}\footnote{si chiama \textsl{buffer circolare} una zona di memoria
  di lunghezza fissa in cui salvare un ammontare limitato dei dati, una volta
  esaurito il buffer i nuovi dati vengono riscritti a partire dalla cima del
  buffer sovrascrivendo quelli precedenti, da cui deriva appunto il nome di
  ``\textsl{circolare}''.} dei messaggi di notifica del kernel. L'uso del
comando consente di visualizzare il contenuto del buffer, che riporta tutto
quanto viene scritto dal kernel, e può essere molto utile per diagnosticare le
cause di alcuni problemi (ad esempio il kernel riporta eventuali errori dovuti
a problemi hardware).

In generale queste stesse informazioni vengono inviate al sistema del
\textit{syslog} (sulla \textit{facility} \texttt{kern}, vedi
sez.~\ref{sec:syslog.conf}) per una registrazione permanente, ma
\texttt{dmesg} consente una visualizzazione immediata del buffer dei messaggi
anche all'utente ordinario, anche se copre soltanto un periodo limitato,
avendo il buffer circolare una dimensione prefissata. Con tutti i kernel
attuali (è stata introdotta nel 2.4.23) la dimensione ha un default di 16kb,
che può essere cambiato con una opzione di compilazione. Inoltre il comando
consente di ottenere le informazioni anche quando il sistema del
\textit{syslog} non è attivo, come può accadere se il sistema ha problemi in
fase di avvio e non lancia il relativo servizio.

Il comando prevede tre opzioni, utilizzabili solo dall'amministratore; con
\texttt{-c} si cancella il contenuto del buffer dopo averlo stampato, con
\texttt{-s} seguito da un valore numerico se ne reimposta la dimensione di
lettura (per leggere interamente un buffer più lungo degli ordinari 16kb) ed
infine con \texttt{-n} si specifica la priorità a partire dalla quale vengono
mostrati i messaggi sulla console. Per ulteriori dettagli si consulti al
solito la pagina di manuale.

Un altro comando molto utile è \index{comando!\texttt{lsof}} \texttt{lsof},
che permette di ottenere la lista di tutti file descriptor aperti all'interno
di tutti i processi attivi nel sistema. Si tenga presente che trattandosi
della lista dei file descriptor, saranno stampati non soltanto quelli associati
a degli ordinari file di dati, ma anche quelli relativi agli altri tipi di
file (quelli di tab.~\ref{tab:file_file_types}) come fifo, socket (compresi
quelli associati alla connessioni di rete) ed anche alle directory, compresi
quelli associati alla directory radice ed alla directory di lavoro di ciascun
processo.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Valore} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{COMMAND}& Il nome del comando (i primi 9 caratteri) associato 
                       al processo.\\ 
     \texttt{PID}    & Il PID del processo.\\
     \texttt{USER}   & Il nome dell'utente (o il suo \textit{user ID}) a cui
                       appartiene il processo.\\
     \texttt{FD}     & per i file aperti direttamente all'interno del processo
                       il numero associato al file descriptor seguito da una
                       delle lettere \texttt{r} (lettura), \texttt{w}
                       (scrittura) e \texttt{u} (lettura/scrittura) per
                       indicare la modalità in cui è aperto; qualora si faccia
                       riferimento ad un file descriptor non aperto
                       esplicitamente dal processo uno dei valori di
                       tab.~\ref{tab:lsof_FD_values}.\\ 
     \texttt{TYPE}   & il tipo di file (quello di
                       tab.~\ref{tab:file_file_types}) identificato con le
                       sigle \texttt{REG} per i file regolari, \texttt{DIR}
                       per le directory, \texttt{LINK} per i link simbolici,
                       \texttt{CHR} per i dispositivi a caratteri,
                       \texttt{BLK} per i dispositivi a blocchi, \texttt{FIFO}
                       per le fifo e le pipe; i socket sono invece riportati
                       per tipo (\texttt{unix} per quelli locali,
                       \texttt{Ix4} per quelli di rete); esistono poi valori
                       speciali come \texttt{DEL} per un file che è stato
                       cancellato o \texttt{NOFD} per un file che non si è
                       potuto aprire.\\  
     \texttt{DEVICE} & identificativo del dispositivo su cui si trova il file,
                       con i valori di \textit{major number} e \textit{minor number}.\\ 
     \texttt{SIZE}   & dimensione del file, se esistente, altrimenti vuoto.\\
     \texttt{NODE}   & numero di \textit{inode} per i file e gli altri oggetti
                       del filesystem, nome del protocollo per i socket di
                       rete.\\ 
     \texttt{NAME}   & nome del file, se questo è presente sul filesystem, le
                       parole chiave \texttt{pipe} e \texttt{socket} per
                       indicare file descriptor associati a \textit{pipe} o
                       \textit{socket} anonimi, e gli estremi della
                       connessione per i socket di rete.\\
    \hline
  \end{tabular}
  \caption{Informazioni di default riportate dall'output di \texttt{lsof}.} 
  \label{tab:lsof_default_infos}
\end{table}

Il comando può essere usato anche da un utente normale, ma per poter avere
tutte le informazioni occorre utilizzarlo con privilegi amministrativi. Se
invocato senza nessuna opzione o argomento il comando stampa la lista di tutti
i file descriptor aperti, riportando in colonna per ciascuno di essi una serie
di informazioni, illustrate nell'elenco di tab.~\ref{tab:lsof_default_infos}.

Il comando supporta una enorme quantità di opzioni che consentono di
controllare e selezionare in maniera dettagliata sia le informazioni da
stampare che quali file descriptor analizzare, per le quali si rimanda alla
lettura della voluminosa pagina di manuale. Vale comunque la pena citare
\texttt{-u} che consente effettuare una selezione per utente, da specificare
come parametro dell'opzione, e \texttt{-p} che consente una selezione per PID,
di nuovo da specificare come parametro, così da ottenere la lista dei file
aperti da un processo. La selezione poi può in entrambi i casi essere
invertita apponendo un carattere ``\texttt{\circonf}'' al parametro.

Infine se si passano uno o più argomenti al comando questi vengono normalmente
interpretati come pathname di file, e verranno riportati solo i risultati dei
file descriptor ad essi corrispondenti. Fa eccezione a questa regola il caso
in cui il pathname specifica il \textit{mount point} di un filesystem (vedi
sez.~\ref{sec:file_disk_management}) nel qual caso verranno mostrati tutti i
file descriptor relativi a tale filesystem.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|c|p{8cm}|}
    \hline
    \textbf{Valore} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{cwd}& directory di lavoro del processo.\\
     \texttt{rtd}& directory radice del processo.\\
     \texttt{txt}& segmento di testo (codice o libreria) del processo.\\
     \texttt{mem}& file mappato in memoria.\\
    \hline
  \end{tabular}
  \caption{Principali valori del campo \texttt{FD} dell'output di
    \texttt{lsof}.} 
  \label{tab:lsof_FD_values}
\end{table}

Uno degli usi più comuni di \texttt{lsof} in ambito diagnostico è quello che
consente di determinare quale processo stia mantenendo occupato un filesystem
che si deve smontare (vedi sez.~\ref{sec:file_disk_management}), sia perché
c'è un file aperto su di esso, sia perché un processo ha la directory di
lavoro corrente all'interno dello stesso. Un esempio di questo utilizzo è il
seguente: 
\begin{Console}
root@monk:~# \textbf{lsof /mnt/}
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
bash    9040 piccardi  cwd    DIR   8,65     4096 20288 /mnt
\end{Console}


Come complemento e alternativa a \texttt{lsof} si può usare il comando
\index{comando!\texttt{fuser}} \texttt{fuser}, che mostra quali processi
stanno usando un certo file, socket o filesystem. Nell'uso più comune il
comando richiede che si indichino file e directory di cui si vogliono
conoscere eventuali utilizzatori come argomenti, stampando per ciascuno
l'elenco dei PID dei processi che li stanno utilizzando seguito da una o più
lettere che ne indicano il tipo di utilizzo, secondo quanto illustrato in
tab.~\ref{tab:fuser_access_type}.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|c|l|}
    \hline
    \textbf{Valore} & \textbf{Significato} \\
    \hline
    \hline
     \texttt{c}& directory di lavoro del processo.\\
     \texttt{e}& eseguibile in esecuzione.\\
     \texttt{f}& file aperto (non mostrato di default).\\
     \texttt{F}& file aperto in scrittura (non mostrato di default).\\
     \texttt{m}& file mappato in memoria.\\
     \texttt{r}& directory radice del processo.\\
    \hline
  \end{tabular}
  \caption{Lettere usate da \texttt{fuser} per indicare il tipo di accesso ad un file.} 
  \label{tab:fuser_access_type}
\end{table}

Dato che il risultato ordinario è poco leggibile è normale usare l'opzione
\texttt{-v} per ottenere una stampa più estesa, in cui viene usata una riga
per ogni processo rilevato, che riporta nell'ordine: l'utente per conto del
quale viene eseguito il comando, il PID del processo, la modalità di accesso
(con i valori sopra menzionati) ed il comando con cui il processo è stato
eseguito. Si può inoltre usare l'opzione \texttt{-k} per inviare un segnale ai
suddetti processi, il default è \texttt{SIGKILL}, ma se ne può specificare un
altro indicandolo con un ulteriore \texttt{-\textsl{SIGNAL}}.

Si può inoltre ottenere l'elenco di tutti i processi che usano un filesystem
usando l'opzione \texttt{-m}, usando come argomento un qualunque file che stia
su quel filesystem (anche se è più comune usarne la directory di \textit{mount
  point}). Infine il comando consente, con l'opzione \texttt{-n}, di ottenere
informazioni anche sui socket di rete, in tal caso occorre passare all'opzione
l'ulteriore argomento \texttt{tcp} o \texttt{udp} per indicare il tipo di
protocollo usato dal socket ed usare come argomento un numero di porta,
seguito eventualmente, separati da virgole, dall'indirizzo locale e remoto del
socket stesso (per i concetti relativi alle reti si rimanda al
cap.~\ref{cha:networks_base}).

Un altro comando diagnostico estremamente potente è
\index{comando!\texttt{strace}} \texttt{strace}, che stampa sullo
\textit{standard error} tutte le \textit{system call} eseguite da un programma
durante la sua esecuzione, consentendo così, come suggerisce il nome, di
tracciare le operazioni effettuate dal programma. Ad esempio se usiamo
\texttt{strace} con il comando \texttt{cat}, si avrà qualcosa del
tipo:\footnote{si noti la redirezione dello \textit{standard output}, che è
  stata eseguita per evitare di mescolare il risultato del comando con quello
  di \texttt{strace}.}
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{strace cat corso.tex > /dev/null}
execve("/bin/cat", ["cat", "corso.tex"], [/* 33 vars */]) = 0
...
open("corso.tex", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=2315, ...}) = 0
read(3, "%% corso.tex\bslash{}n%%\bslash{}n%% Copyright (C) "..., 4096) = 2315
write(1, "%% corso.tex\bslash{}n%%\bslash{}n%% Copyright (C) "..., 2315) = 2315
read(3, ""..., 4096)                    = 0
close(3)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?  
\end{Console}
%$

Una spiegazione completa di questo estratto, da cui per semplificare la
lettura si sono eliminate tutte le operazioni di inizializzazione successive
la chiamata iniziale a \texttt{execve} che è quella che mette in esecuzione
\texttt{cat}, eccede ovviamente quanto sia possibile affrontare in questa
sede, dato che necessiterebbe di una spiegazione dettagliata del significato
delle varie \textit{system call}, argomento che attiene alla programmazione, e
non alla amministrazione di sistema.\footnote{gli interessati a questo
  argomento possono al solito fare riferimento a \cite{GaPiL}, il cui scopo è
  proprio quello di documentare adeguatamente le interfacce di sistema di
  Linux.} È comunque possibile fare una lettura superficiale che ci mostra
come prima venga aperto il file \texttt{corso.tex} sul file descriptor 3 (il
risultato della \texttt{open}), e poi venga letto da questo il contenuto (con
la \texttt{read}), che viene immediatamente dopo scritto (con la
\texttt{write}) sul file descriptor 1, che abbiamo già detto essere appunto
quello associato con lo \textit{standard output}.

Anche solo questo esempio ci consente di vedere come \texttt{strace} consenta
di analizzare le richieste fatte da un programma, ed in particolare è molto
utile vedere quali file il programma cerca di aprire (con la funzione
\texttt{open}). In questo modo diventa possibile capire eventuali cause di
malfunzionamenti dovuti alla ricerca di file assenti o diversi da quelli che
si supponevano essere quelli effettivamente utilizzati, o vedere in quale
operazione può risultare bloccato un certo programma.

In genere, come nell'esempio precedente, si usa \texttt{strace} passandogli
come argomento il comando che si vuole analizzare (e le eventuali opzioni ed
argomenti dello stesso), ma è possibile anche tracciare un programma già in
esecuzione usando l'opzione \texttt{-p}, che prende come parametro il PID del
processo che si vuole analizzare. Inoltre con \texttt{-o} si può far scrivere
i risultati su un file qualunque (passato come parametro) invece che sullo
\textit{standard error}, e se il nome del file inizia con una ``\texttt{|}'' i
risultati saranno inviati sullo \textit{standard input} del comando scritto di
seguito.

Si possono infine selezionare le \textit{system call} che si vogliono
tracciare con l'opzione \texttt{-e}, cui far seguire un parametro in cui le si
elencano nella forma \texttt{trace=\textsl{sysc1},\textsl{sysc2},...}, e si
può fare una selezione negativa apponendo alla lista il carattere
``\texttt{!}''.  Come \texttt{lsof} anche \texttt{strace} fornisce numerose
opzioni che permettono di controllare e selezionare le informazioni da
stampare, per le quali si rimanda alla lettura della pagina di manuale.

Un altro comando utile a scopi diagnostici è \index{comando!\texttt{strings}}
\texttt{strings} che consente di effettuare una ricerca sulle stringhe di
testo presenti all'interno di un file binario e stamparle sullo
\textit{standard output}. Il comando è particolarmente utile quando si
vogliono cercare le stringhe presenti all'interno dei comandi ed in
particolare può aiutare ad identificare, dai relativi pathname, i file di
configurazione che questo usa di default, con qualcosa del tipo:
\begin{Example}
strings /usr/bin/crontab | grep /etc
\end{Example}

Il comando al solito prende varie opzioni che consentono di controllarne il
comportamento, come \texttt{-e} che consente di specificare una codifica, o
\texttt{-n} che consente di indicare la dimensione minima della stringa
identificata da una sequenza di caratteri stampabili di dimensione superiore
al valore specificato da tale opzione (il default è 4). Al solito per i
dettagli si faccia riferimento alla pagina di manuale.

%TODO trattare ltrace


\subsection{I comandi per la verifica di integrità}
\label{sec:integrity_check_cmd}

Si sono raccolti in questa sezione i programmi che vengono utilizzati per
verificare l'integrità e l'autenticità di un file. Il compito come vedremo in
realtà è tutt'altro che banale, in particolare per quanto riguarda la
definizione di ciò che si intende per ``\textsl{autentico}''.

Una prima serie di questi comandi serve a stabilire se un file non presenta
modifiche rispetto ad un altro, considerato come originale, verifica che in
genere si effettua dopo averlo scaricato. La verifica viene fatta attraverso
una cosiddetta ``\textsl{somma di controllo}'' o \textit{checksum} associata
al file originale, che consente di controllare se la copia ottenuta è
identica.

\itindbeg{hash}

Una \textit{checksum} non è altro che una opportuna funzione matematica che ha
la caratteristica di dare risultati molto diversi anche per piccole differenze
nell'input, pertanto si diventa in grado di rilevare subito eventuali
modifiche. Il concetto di base è che la \textit{checksum} viene calcolata con
il file originale, che si considera come copia di riferimento, e distribuita
con esso. Scaricando (o ottenendo altrimenti una copia) si potrà verificare,
ricalcolando su di essa la somma, che questo porti allo stesso risultato,
concludendo che il file è identico.

Queste funzioni vengono anche chiamate funzioni di \textit{hash} in quanto una
richiesta comune è che possano dare risultati diversi in presenza di dati in
ingresso diversi di dimensioni qualunque, producendo comunque un valore
numerico di dimensione fissa, detto appunto \textit{hash}. Questo poi deve
avvenire con probabilità trascurabile di ``\textsl{collisioni}'', cioè del
caso in cui due input diversi generano lo stesso \textit{hash}.  Si parla poi
di \textit{hash crittografico} quando noto un \textit{hash} è sostanzialmente
impossibile ricostruire il dato che l'ha generato o trovare un dato
alternativo che generi lo stesso valore (per una trattazione dell'argomento si
consulti sez.~1.2.4 di \cite{SGL}).

\itindend{hash}

Il programma più semplice che si può usare a questo scopo è
\index{comando!\texttt{cksum}} \texttt{cksum}, che per il calcolo della somma
usa un algoritmo chiamato CRC, molto semplice e veloce, ma che non ha nessuna
delle caratteristiche di un \textit{hash crittografico}, in quanto è
relativamente semplice generare file che portino allo stesso risultato data
una \textit{checksum} qualunque e le collisioni sono abbastanza frequenti. Il
comando serve solo per una verifica minimale, e si usa invocandolo su uno o
più file, nel qual caso per ciascuno di essi stamperà a video una riga con il
valore del CRC, seguito dalla dimensione e dal nome del file. Se non si
specifica nessun file il programma viene eseguito sullo \textit{standard
  input}.

Se però si vuole avere la sicurezza che nessuno abbia modificato un file di
cui si possiede una \textit{checksum} occorrerà usare un programma diverso,
dato che \texttt{cksum} non fornisce le garanzie di un \textit{hash
  crittografico}, in quanto è relativamente semplice modificare un file e
mantenere identico il valore del suo CRC. Questo rende inadeguato il programma
ad una verifica di una eventuale compromissione dei propri dati o programmi da
parte di un attaccante malevolo.

Per poter garantire l'impossibilità di avere una modifica che sfugga ad un
controllo occorre allora che l'algoritmo utilizzato garantisca le
caratteristiche di un \textit{hash crittografico}, e cioè sostanziale
impossibilità di generare lo stesso \textit{hash} dell'originale in un file
modificato. A lungo il programma usato per fare questo è stato
\index{comando!\texttt{md5sum}} \texttt{md5sum}, che usa per il calcolo un
algoritmo chiamato MD5, considerato in grado di rispondere al requisito. 

Anche in questo caso il programma richiede che si specifichi come argomento
uno o più file da controllare, stampando per ciascuno di essi una riga con il
valore dell'\textit{hash} MD5 (un numero a 128 bit in forma esadecimale)
seguito dal nome del file. Di nuovo se non si specifica nessun file il
programma opera sullo \textit{standard input}. Un esempio di uso del programma
è il seguente:
\begin{Console}
piccardi@monk:~/truedoc/sicurezza$ \textbf{md5sum *.tex} 
17d80d7547d6a7bbc2d84bfaec9ee5f2  cryptoapp.tex
9f3dfec4f383eee3e75a374c5f07a056  firewall.tex
4b10bef0b1ada92990ed190a693b3bb7  gpg.tex
be501bad4f38ce267c227f10788f16db  ids.tex
3a3c65cfe2b1c794efbc6e8b70969ccb  introsec.tex
ac29b2b82fc88ffaa12f7aa4920f412a  sicurezza.tex
\end{Console}
%$

Si può inoltre utilizzare l'opzione \texttt{-c}, che consente di indicare come
unico argomento un file che contenga una lista di risultati precedenti. Il
comando verrà applicato a ciascuno dei file elencati, segnalando eventuali
differenze, diventa così possibile effettuare velocemente un controllo di
integrità se ci si è salvati da qualche parte l'uscita di una invocazione
precedente.

Da qualche anno però sono stati scoperti seri problemi nell'algoritmo MD5,
benché resti ancora difficile ottenere uno stesso \textit{hash} con modifiche
arbitrarie, è diventato possibile generare delle collisioni e per questo oggi
l'algoritmo non viene più considerato sicuro anche se la complessità di un
attacco mirato a mascherare una modifica ad un file resta abbastanza alta. Al
suo posto comunque viene consigliato un algoritmo alternativo, lo SHA.

In realtà in questo caso si tratta di una famiglia di algoritmi, in quanto la
dimensione dell'\textit{hash} è variabile, ed esistono varie versioni
dell'algoritmo a partire dai 160 bit della prima versione, denominata SHA1.
Con la versione successiva, chiamata genericamente SHA2, sono inoltre
possibili varianti con dimensioni diverse dell'\textit{hash} che vengono
identificate apponendo al nome SHA il numero di bit usati per l'\textit{hash}
(224, 265, 384, 512). Benché siano state trovate delle debolezze
nell'algoritmo SHA1, queste al momento prospettano solo una riduzione della
complessità nella generazione delle collisioni. 

Le stesse debolezze sono al momento solo teorizzate per SHA2 per la similarità
dell'algoritmo, ma senza nessun risultato concreto. Trattandosi comunque di
debolezze che riducono la complessità di calcolo nella ricerca di una
possibile collisione, esiste comunque la possibilità di riportarla ad un
valore che renda impraticabile qualunque attacco semplicemente usando un
\textit{hash} di dimensioni superiori. Per questo motivo l'algoritmo ad oggi
viene comunque considerato sicuro, e nella versione a 512 bit viene dichiarato
adeguato anche per l'impiego in condizioni di massima sicurezza.

Il comando che si può utilizzare per creare e verificare delle
\textit{checksum} SHA è \index{comando!\texttt{shasum}} \texttt{shasum}, che
di default usa l'algoritmo SHA1. Con l'opzione \texttt{-a} si può però
richiedere l'uso di una qualunque delle versioni alternative, indicando il
relativo numero di bit.\footnote{in realtà il comando \texttt{shasum} è un
  \textit{wrapper} che invoca una serie di altri comandi (\texttt{sha1sum},
  \texttt{sha224sum}, \texttt{sha256sum}, ecc.) a seconda della versione
  scelta.} Il programma usa gli argomenti allo stesso modo di \texttt{md5sum},
e produce un risultato analogo, si avrà così:
\begin{Console}
piccardi@monk:~/truedoc/sicurezza$ \textbf{shasum *.tex} 
5f4c0cc0be9b6ae0331b45c7feef861a3bcf1caf  cryptoapp.tex
938541121a926948ff1f2125d36837177882b6b6  firewall.tex
a4f0609fc2309dea6e75bad0a959f34262e9fd64  gpg.tex
9437d7bc0e73e695de7a567eef527af4f5c14e4b  ids.tex
20f70ca35a77d10c3c9d769b2381b7c783a1961b  introsec.tex
3548297780fa69bdf0a8f91b184993d835465e52  sicurezza.tex
\end{Console}
%$

Il comando riconosce anche l'opzione \texttt{-c} con lo stesso significato
di \texttt{md5sum}, se allora si salva il precedente risultato con un comando
come \texttt{shasum *.tex > lista.sha}, si potrà verificare che nessun file è
stato modificato con:
\begin{Console}
piccardi@monk:~/truedoc/sicurezza$ \textbf{shasum -c lista.sha}
cryptoapp.tex: OK
firewall.tex: OK
gpg.tex: OK
ids.tex: OK
introsec.tex: OK
sicurezza.tex: OK
\end{Console}
%$

Se non si vuole che vengano ristampate le verifiche ma che il comando riporti
nello stato di uscita la corrispondenza o meno della verifica, si può usare
l'opzione \texttt{-s}, per tutti dettagli e l'elenco completo delle opzioni si
consulti la pagina di manuale.

Benché i comandi precedenti consentano di verificare l'integrità di un file
una volta che si disponga della relativa \textit{checksum}, questo non ci
aiuta se non siamo in grado di stabilire se anche quest'ultima è
``\textsl{autentica}''. Il punto cruciale è che se un attaccante può
sostituire un file, ad esempio quello di un pacchetto che si vuole installare,
con una sua copia opportunamente ``\textsl{modificata}'', potrà anche generare
la relativa \textit{checksum}, e la verifica della stessa diventa
inutile. 

I comandi illustrati possono servire allora a rilevare eventuali modifiche
rispetto a file dei quali si è ottenuta, in maniera indipendente e verificata,
una \textit{checksum} che si sa essere quella giusta. L'unico modo per
assicurarsi, quando si scarica un file dalla rete, che la relativa
\textit{checksum} non sia stata creata ad arte, è quello di ricorrere alla
cosiddetta \textsl{firma digitale} ed alla crittografia a chiave
asimmetrica. L'argomento va al di là dello scopo di questo testo (ma è
trattato in dettaglio nella sez.~1.2 e nel capitolo 2 di \cite{SGL}), ma il
concetto di base è che è possibile apporre firme digitali su un file, che non
solo attestano che questo non è stato modificato, ma anche che il file stesso,
o la \textit{checksum} che vi si è allegata, è proprio quella generata
dall'autore della firma digitale.

Benché esistano diverse possibilità, il modello utilizzato nel mondo GNU/Linux
per ottenere questo tipo di garanzia, ed utilizzato da tutte le distribuzioni
per garantire ad esempio l'autenticità dei propri pacchetti software, è quello
di firmare i singoli pacchetti, gli hash crittografici, e nel caso di Debian
pure il contenuto generale dell'archivio, con il programma GPG.  Non
tratteremo in questa sede i dettagli del modello del \textit{Web of trust} e
le caratteristiche generali di GPG, (che sono affrontati in maniera completa
in sez.~2.2 di \cite{SGL}), limitandoci ad esporre alcuni concetti in maniera
molto generica ed a riprendere da quella sezione solo la parte relativa alla
sintassi del comando.

Il programma, il cui nome è l'acronimo di \textit{GNU Privacy Guard} è una
reimplementazione di un programma, PGP (acronimo di \textit{Pretty Good
  Privacy}), nato per cifrare e firmare i messaggi di posta elettronica. Il
programma prevede che un utente venga identificato da una coppia di chiavi,
cui vengono associati uno o più identificativi, in genere espressi nella forma
di un indirizzo di posta elettronica. La chiave pubblica viene distribuita e
può essere usata da chiunque per creare messaggi cifrati che possono essere
solo decifrati dalla chiave privata, che invece deve essere mantenuta e
protetta con la massima cura, in quanto oltre a decifrare può anche essere
utilizzata per realizzare una firma digitale.

In genere il programma viene usato per corrispondere, nel qual caso ci si
procura la chiave pubblica del destinatario (esistono anche dei
\textit{keyserver} che raccolgono le chiavi pubbliche di coloro che le
vogliono pubblicare) e si cifra il messaggio con quella in modo che solo lui
possa decifrarlo. Ma si può usare il programma anche per cifrare i propri
file, usando la propria chiave pubblica, in modo da poter essere i soli a
decifrarli.

Un impiego di questo tipo potrebbe essere quello in cui si cifrano dei file
(ad esempio un backup) prima di inviarli su un server pubblico, il vantaggio
in questo caso è che, non essendo la propria chiave privata necessaria per
cifrare, questa può essere mantenuta in sicurezza fuori dal computer su cui si
cifra il file, ed una compromissione dello stesso non comporta la possibilità
di decifrare quanto è stato cifrato in precedenza (cosa che per un backup però
avrebbe poco senso, essendo in tal caso disponibili i file originali).

Oltre che cifrare i file GPG consente anche di firmarli, se infatti si genera
un \textit{hash crittografico} di un file e lo si cifra con la propria chiave
privata si ottiene appunto una firma digitale. In tal caso infatti una persona
in possesso della nostra chiave pubblica (potenzialmente chiunque) potrà
decifrarlo. Ma dato che solo con la chiave privata si può generare un
messaggio decifrabile con la chiave pubblica, si dimostra che chi ha creato
quella ``firma'' possiede la chiave privata (e se ne certifica l'identità),
inoltre con l'\textit{hash crittografico} presente nella firma si potrà
verificare anche che il file è integro.

In questo caso, anche se un attaccante potesse sostituire un eventuale
pacchetto software, la sua \textit{checksum}, e la firma digitale non
riuscirebbe comunque a passare inosservato. Infatti chiunque abbia avuto cura
di procurarsi in anticipo la chiave pubblica con la quale lo sviluppatore
firma il pacchetto garantendone autenticità ed integrità, rileverebbe
immediatamente che la firma non corrisponde a quella aspettata, dato che solo
la chiave privata dello sviluppatore può generare una firma digitale
``\textsl{corretta}''.

Si noti comunque che anche in questo caso la sicurezza non può essere
assoluta, la chiave privata dello sviluppatore potrebbe essere stata
compromessa, ottenendo la possibilità di generare una firma corretta, oppure
qualcuno potrebbe averci ingannati riuscendo a spacciare la sua chiave pubblica
per quella dello sviluppatore, e con questo la possibilità di farci credere
che la firma sia corretta. Ma la situazione resta comunque nettamente migliore
rispetto al precedente caso di controllo basato sulla sola verifica di un
\textit{hash crittografico}.

Si noti come in questo caso sia critico, come lo sarà per le chiavi pubbliche
di SSH (vedi sez.~\ref{sec:net_ssh}) accertarsi che le chiavi pubbliche che si
utilizzano siano effettivamente quelle ``\textsl{giuste}''. In questo viene in
aiuto il modello del \textit{web of trust} che GPG utilizza, per il quale di
nuovo si rimanda alla lettura della sez.~2.2 di \cite{SGL}.

\input{../sicurezza/gpg.tex}

La gestione del livello di fiducia, così come le varie operazioni di gestione
delle chiavi, si effettuano con la specifica opzione \texttt{-{}-edit-key} del
comando che richiede si passi come argomento un \textit{user ID} o un
\textit{Key-ID}. L'opzione stampa i dati riassuntivi della chiave scelta (con
i vari \textit{User ID} ad essa associati) e poi porta su una riga di comando
interna da cui si possono eseguire le varie operazioni tramite altrettanti
comandi. Di questi citeremo soltanto \texttt{help}, che consente di stampare
una lista degli stessi, per una trattazione più dettagliata si rimanda alla
parte finale della sezione 2.2.3 di \cite{SGL}.


% LocalWords: shell Arnold Robbins info sez coreutils toolbox like cap ls ps
% LocalWords: cp chmod kernel Bourne POSIX sh bash ash ksh again history SHA
% LocalWords: Korn kilobyte zsh csh tcsh IFS library fig getopt rm pippo pluto
% LocalWords: gzip gunzip built Di Variables tab PROMPTING May username RedHat
% LocalWords: quest'ultime BUILTIN COMMANDS unset rw Aug echo HOSTNAME OSTYPE
% LocalWords: PWD GLOBIGNORE filename globbing HISTFILE HISTFILESIZE HISTSIZE
% LocalWords: HOME home PATH VAR declare tracing env ignore TERM JCPU PCPU Jul
% LocalWords: path search pathname filesystem sbin rehash which type is DOS cg
% LocalWords: builtin unalias wildcard VMS pdf baseadm netadmin fdl aux tex wh
% LocalWords: log toc texput LaTeX config Entries Repository Root CVS command
% LocalWords: expansion cat cannot lstat such arithmetic chown root dell'I of
% LocalWords: error descriptor system wide profile for the and cmd compatible
% LocalWords: shells less REDIRECTION filecompleto append fifo sort   shasum
% LocalWords: pipelining Scripting bat FHS bin GRAMMAR loader lib ELF Python 
% LocalWords: scripting Perl README PID Parameters if then fi elif done  gpg
% LocalWords: while until expr esac var function seq true l'AND l'OR effective 
% LocalWords: group inode eq ge gt lt subshell source umask executed see it
% LocalWords: examples files located doc package bashrc exists running don't %
% LocalWords: interactively put lines options HISTCONTROL ignoredups enable ll 
% LocalWords: support also add handy aliases dumb eval dircolors format vdir 
% LocalWords: fancy this an xterm title to programmable ln git svn rpc xz 
% LocalWords: completion features you need it's already enabled mkdir libc gid 
% LocalWords: switch process renice version tabsize insensitive updatedb cron 
% LocalWords: find TESTS ACTIONS OPERATORS maxdepth mindepth follow mount name 
% LocalWords: regex perm atime ctime mtime amin cmin mmin anewer cnewer mnewer 
% LocalWords: links iname ipath size uid print fprint exec NUL old not grep ac 
% LocalWords: egrep regular expression matching alnum alpha cntrl digit graph 
% LocalWords: lower punct upper xdigit subpattern patent must licensed at all 
% LocalWords: everyone's restricted from conspicuously appropriately  wrapper
% LocalWords: publish each copy with work based foundation write we sometimes 
% LocalWords: pager num keybinding pre Octal Dump head tail split xaa xab xac 
% LocalWords: cut tr bell backspace form feed new line return escape LZMA 
% LocalWords: pr fmt fold keyserver keyring unxz cursor ctrl hardcopy sess
% LocalWords: nl expand unexpand sed regexp sima txt lzma hold pid host fuser
% LocalWords: sottocomandi touch uniq count cksum sum checksum CRC hash RTFM
% LocalWords: read manual fucking call dev passwd whatis change apropos chage
% LocalWords: expiry information HOWTO documentation Project os all'HTML 
% LocalWords: Italian usenet client news comp lang FAQ Frequently Asked UTC YY 
% LocalWords: Question calendar Jan Epoch GMT Greenwich Mean l'UTC timer sys 
% LocalWords: scheduler ldap sleep dual Fri Sep CEST MMDDhhmm ss DD hh CCYY fR 
% LocalWords: Operation permitted month hwclock seconds systohc hctosys xargs 
% LocalWords: yes emacs xemacs Extensible MACro Eight Megs Constantly Swapping 
% LocalWords: Control Shift debug tetrix doctor Lisp minibuffer INS control wq 
% LocalWords: ESC vim nomefile dw l'autocompletamento nell'inode result uname 
% LocalWords: dd visual ZZ ZQ joe wordstar jmacs jed evidenziazione pine gedit 
% LocalWords: semigrafica mcedit Midnight Commander semigrafico Norton KDE xr 
% LocalWords: kate nedit gvim rwxr atici l'evidenziazione nt ot aeiou embedded
% LocalWords: Sarge rbash color ntpdate NTP Protocol hain Dec adjust sec join 
% LocalWords: Posix whereis slocate Secure hexdump Hexadecimal hd job TTY VT 
% LocalWords: multitasking getty tty FN session PGID SID STAT init pty helper 
% LocalWords: pts sshd priv xmms xdvi gs forwarding SIGTTIN SIGTTOU Stopped bg 
% LocalWords: SIGSTOP fg jobs SIGINT SIGQUIT foreground kill wait SIGHUP nohup
% LocalWords: hungup disown environment pag DEVICE SIGTSTP exit variable its 
% LocalWords: espansion Parameter opt typeset LC EVALUATION string subst Names
% LocalWords: autocompletamento Readline readline advadmin corsoFSE netbase as 
% LocalWords: netdns netinter netlpi ordadmin stradmin arg condition tmp dmesg 
% LocalWords: value list break logout CDROM prunefs prunepaths localuser Sid 
% LocalWords: sets variables used filesystems pruned NFS nfs afs proc smbfs am 
% LocalWords: autofs iso ncpfs devpts ftpfs devfs mfs sysfs paths amd alex sfs 
% LocalWords: netpaths added run nobody priority higher number means usually 
% LocalWords: NICE spool notslocate str tag elencofinale troff ellington USB 
% LocalWords: mandb pages manpath MANDATORY MAP SECTION Hierarchy whoami voice 
% LocalWords: groups cdrom plugdev lpadmin saned vboxusers runlevel users who 
% LocalWords: logname uptime days load average IDLE last Thu still logged Wed 
% LocalWords: reboot Sun wtmp begins lastb ispell ric wq sost perl WHAT REG 
% LocalWords: dell'autocompletamento syslog facility kern klog lsof socket CHR
% LocalWords: BLK SMP FD NOFD major NODE cwd rtd mem point strace vars UTF CH 
% LocalWords: execve fstat read close strings compress unzip gz zcat bzip bz 
% LocalWords: bzcat bunzip Field Separator dash watch SHLVL Latex firewall  ids
% LocalWords: Makefile TODO IPSEC modes scheme iptraf png openvpn images 
% LocalWords: commons mailservices webservices access Squeeze handled pam 
% LocalWords: interpreter setting ssh logins install configure libpam when
% LocalWords: includes exits leaving clear screen increase should unless may
% LocalWords: want different defaults debian chroot uncomment following BIND 
% LocalWords: colorized avoid making mistakes mlocate merging readonly posix 
% LocalWords: errexit noclobber noglob nounset prunenames PRUNE MOUNTS cifs 
% LocalWords: tmpfs usbfs udf bind general public license take away xzcat your
% LocalWords: freedom share works contrast intended guarantee unlzma lzcat
% LocalWords: names contributors


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "corso"
%%% End: 
