Generalità sui comandi
L'interazione in un terminale avviene tramite l'inserimento di
appositi comandi. Ogni comando è in realtà il nome di un programma,
che viene ricercato in alcune cartelle pre-determinate. Solitamente
queste sono /bin
, /usr/bin
, e
talvolta /usr/local/bin
. In quest'ultima cartella è
usuale installare nuovi comandi creati dall'utente, oppure installati
come applicazioni di terze parti.
Il comando ls
Uno dei primi comandi con cui si fa conoscenza è ls
, che sta per
"list"; è già stato usato per ottenere la lista dei file nella propria home.
Permette di ottenere una lista dei file in una directory qualunque.
ls
per ottenere una lista dei
file nella directory corrente. Ad esempio:
$ lsSe la cartella è vuota, ci si aspetta che il comando non ritorni nessun output. Tuttavia, nella home ci sono dei file, solamente che sono nascosti, perché il loro nome comincia con un punto. Per visualizzare la lista completa dei file si può dare il comando
ls -a
.
Si noti che, quando viene chiesto di vedere anche i file nascosti, vengono sempre mostrati due file particolari:
.
che rappresenta la cartella corrente...
che rappresenta invece la cartella genitore (i.e., quella superiore a quella corrente — i concetti di figli e genitori verranno chiariti nella prossima pagina).
Ogni comando può accettare degli argomenti, ovvero una lista di stringhe (i.e., sequenze di
caratteri) successive al nome del comando, che si possono utilizzare per specificare l'azione
da effettuare. Queste vengono usualmente distinte in opzioni, o flag, che
tipicamente iniziano con il simbolo -
, e genericamente
argomenti (tutti gli altri).
Tipicamente i flag si distinguono in quelli brevi, identificati da una linea ed una
sola lettera, e quelli lunghi, che iniziano con due linee seguita poi da parola chiave
più lunga. A volte esiste solo una versione (lunga o corta), mentre altre volte sono
accettate entrambe le possibilità. Ad esempio, è possibile chiedere a ls
di invertire l'ordine in cui vengono listati gli argomenti utilizando il flag -r
,
oppure --reverse
.
È possibile utilizzare la flag -l
per chiedere a ls
una lista più dettagliata, oppure specificare come argomento il nome di una cartella diversa da
quella corrente di cui listare il contenuto. Non esiste una versione lunga di questa opzione.
-l
per chiedere ad ls
di fornire una lista
dettagliata del contenuto della cartella ~/.ssh/
, dove nell'esercizio precedente
dovrebbero essere state salvate le chiavi crittografiche. Il comando dovrà restituire un
output simile al seguente:
ls -l ~/.ssh -rw------- 1 leonardo leonardo 396 lug 3 08:23 authorized_keys -rw-rw-r-- 1 leonardo leonardo 888 lug 21 16:23 config -rw------- 1 leonardo leonardo 1679 lug 3 08:23 id_rsa -rw-r--r-- 1 leonardo leonardo 396 lug 3 08:23 id_rsa.pub -rw-r--r-- 1 leonardo leonardo 91416 lug 21 16:06 known_hostsHint: si torni all'esercizio 1 per vedere come digitare il simbolo
~
.
ls -l
si ottengono molte informazioni, organizzate per colonne. Possiamo analizzare ad esempio il file id_rsa.pub
, la chiave pubblica utilizzata per
l'autenticazione.
-rw-r--r--
indica i permessi di lettura/scrittura/esecuzione di questo file, per il proprietario, il gruppo, e tutti gli altri. Il primo carattere può essere-
per i file, e viene marcato con unad
per le cartelle (o directory). I seguenti tre caratteri (in questo casorw-
) indicano la presenza dei permessi di lettura, scrittura, ed esecuzion per il proprietario. In questo caso il file è leggibile e scrivibile ma non eseguibile (i.e., non è un programma/comando); in caso contraio, il permesso sarebberwx
. Seguono poi gli analoghi permessi per il gruppo (r--
) e per gli altri utenti (r--
); entrambi possono leggere il file, ma non scriverlo. Si osservi che la chiave privata (id_rsa
) non è invece leggibile dagli altri utenti.1
indica il numero di inode che puntano a questo file (questo verrà discusso nel dettaglio in seguito, per il momento si può ignorare).leonardo
, sulla seconda colonna, è l'utente proprietario del file.- Sulla terza colonna troviamo nuovamente
leonardo
, questa volta ad indicare il gruppo proprietario del file. - Il numero
396
indica la dimensioni in byte del file. - La data
lug 3 08:23
indica la data di ultima modifica. id_rsa.pub
è il nome del file.
Il comando man
Come fare a sapere quali opzioni accetta un comando? Ad esempio, è possibile chiedere al
comando ls
di listare i file in ordine alfabetico inverso? In generale ci sono
due strategie per rispondere a questa domanda:
-
Molti comandi accettano un'opzione
-h
oppure--help
, con la quale mostrano una breve (o talvolta meno breve) lista delle opzioni disponibili. -
In alternativa, quasi tutti i comandi su Linux forniscono un
manuale di accompagnamento, in cui viene spiegato come chiamare
il comando, e tutte le opzioni che sono disponibili. Questo
manuale è quasi sempre più completo dell'output del comando
con
-h
.
man
.
ls
usando il
comando man ls
; si determini l'opzioni necessaria per
invertire l'ordine degli elementi, e la si usi per ottenere una
lista dei file nella directory corrente in ordine alfabetico
inverso. Per uscire dal manuale, si utilizza il
tasto q
.
man man
.
Redirigere l'output
Un comando lanciato da terminale può stampare dell'output, e leggere dell'input.
Per la seconda operazione, utilizza un canale detto standard input,
abbrevito in stdin
. Per stampare, invece, esistono due possibilità:
lo standard output (stdout
), e lo
standard error (stderr
). A prima vista, le stampe
effettuate su questi due canali appaiono identiche, ma è possibile
trattarle in modo diverso.
Molto spesso può essere utile salvare l'output di un comando su un file,
invece di visualizzarlo sul terminale. Per ottenere questo effetto, è
sufficiente utilizzare il simbolo >
. Questo è uno speciale
comando che permette di redirigere lo standard output su un file, ad esempio
con la sintassi:
$ miocomando > miofile.txt
Per impratichirsi con la redirezione dell'output, è molto utile il
comando echo
, che semplicemente stampa gli argomenti
che gli vengono passati. Ad esempio:
$ echo ciao ciao
Il terminale interpreta gli spazi come separazione degli argomenti passati
ad un comando, per cui l'istruzione echo ciao a tutti
viene interpretata
come un comando con tre argomenti, rispettivamente ciao
, a
,
e tutti
. Normalmente, echo
stampa tutti gli argomenti
che riceve separati da spazi, quindi l'effetti finale del comando
$ echo ciao a tuttiè apparentemente quello atteso. Tuttavia, cosa succede aggiungendo ulteriori spazi fra le parole? Per fare in modo che il comando
echo
tratti l'argomento
come unico, dobbiamo usare le virgolette:
$ echo "ciao a tutti"oppure
$ echo 'ciao a tutti'L'uso degli apici singoli o doppi non è equivalente, ma la differenza verrà discussa quando si parlerà di variabili.
echo
con la redirezione
dell'output per creare un file prova.txt
che contenga
il testo "Questo è un file di prova". Verificare il contenuto del
file con il comando cat prova.txt
.
Lo standard error viene utilizzato solitamente per i messaggi d'errore.
Rediregere l'output con >
non ha effetto su queste stampe.
ls file-che-non-esiste
, dove
file-che-non-esiste
è un qualsiasi nome di file che non
esiste nella directory corrente. Il comando stamperà un messaggio d'errore.
Provare a redirigere l'output su un file, ad esempio output.txt
,
ad esempio con il comando
$ ls file-che-non-esiste > output.txtCosa succede? Cosa contiene il file
output.txt
? Controllare con
il comando cat
.
I canali stdin
,stdout
, e stderr
, sono identificati
dal sistema operativo con dei numeri interi, detti file descriptor. In particolare,
questi sono rispettivamente 0
, 1
, e 2
.
$ ls file-che-non-esiste 2> output.txt > output1.txtredirige lo stderr sul file
output.txt
, e lo standard output su output1.txt
.
Confrontare il comportamento con il comando precedente. È possibile usare una sintassi simile per redirigere un canale nell'altro. Ad esempio, tramite il comando:
$ ls file-che-non-esiste 2>&1si può mandare lo stderr nello stdout. Il simbolo
&1
sta ad indicare
l'indirizzo dello stream identificato dall'intero 1
. La sintassi è
molto simile a quella utilizzata in C per ottenere l'indirizzo in memoria di una
variabile.
Sostituendo il simbolo >
con >>
, è possibile
concatenare del testo ad un file già presente; il simbolo >
,
al contrario, sovrascrive sempre il contenuto del file. Anche questo simbolo
si può far precedere dall'intero che rappresenta lo stream, ad esempio
2>>
per lo stderr.
In maniera analoga, è possibile utilizzare un file come input di un comando,
tramite il simbolo <
. Ad esempio, supponiamo di avere il file
miofile.txt
salvato nella directory corrente. Allora il comando
$ comando < miofile.txtleggerà il contenuto del file come input, invece che chiederlo all'utente.
Comporre comandi diversi
Una potente caratteristica del terminale in Linux è che permette di comporre i comandi
come fossero funzioni, fornendo l'output di uno come input dell'altro. La notazione matematica
$g\circ f(x) = g(f(x))$ in un terminale si scrive come f | g
.
Per fare un esempio pratico, si consideri un nuovo comando, di nome
bc
. Questo è una specie di calcolatrice, che a meno di impostazioni
diverse lavora con gli interi.
bc
, ed inserire
qualche operazione aritmetica (ad esempio: 2 + 3
, o 8 / 5
);
verificare il
funzionamento del programma, e poi digitare la combinazione di tasti
CTRL + D
per uscire (oppure scrivere quit
e
premere invio). È possibile utilizzare il comando bc
anche in modo non interattivo,
utilizzando un file per dare i comandi in input.
2 + 3
utilizzando il comando
$ echo "2 + 3" > file.txtControllare il contenuto inserito utilizzando il comando
cat
.
Utilizzarlo come input per il comando bc
, dando il comando
$ bc < file.txtLo stesso risultato si sarebbe potuto ottenere senza bisogno di un file ausiliario componendo l'output il comando
echo "2 + 3"
, che stampare la stringa 2 + 3
,
con l'input del comando bc
. Questo si ottiene con il comando
$ echo "2 + 3" | bc
Si provi ad inventare degli esempi più interessanti.