Corso Linux Base – Lezione 6
Questa lezione tratta della gestione di file e directory su Linux usando gli strumenti da riga di comando.
Un file è una raccolta di dati con un nome e un insieme di attributi. Se, ad esempio, dovessi trasferire alcune foto dal tuo telefono a un computer e dare loro un nome, ora avresti un mucchio di file di immagini sul tuo computer. Questi file hanno attributi come l’ora dell’ultimo accesso o della modifica del file.
Una directory è un tipo speciale di file utilizzato per organizzare i file. Un buon modo di pensare alle directory è come le cartelle utilizzate per organizzare i documenti in un armadio. A differenza delle cartelle di documenti cartacei, è possibile inserire facilmente directory all’interno di altre directory.
La riga di comando è il modo più efficace per gestire i file su un sistema Linux. Gli strumenti della shell e della riga di comando hanno funzionalità che rendono l’utilizzo della riga di comando più veloce e più semplice di un file manager grafico. In questa lezione utilizzerai i comandi ls, mv, cp, pwd, find, touch, rm, rmdir, echo, cat e mkdir per gestire e organizzare file e directory.
Case Sensitive
A differenza di Microsoft Windows, i nomi di file e directory su sistemi Linux fanno distinzione tra maiuscole e minuscole. Ciò significa che i nomi /etc/ e /ETC/ sono directory diverse.
Prova i seguenti comandi:
$ cd /
$ ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
$ cd ETC
bash: cd: ETC: No such file or directory
$ pwd
/
$ cd etc
$ pwd
/etc
Il comando pwd mostra la directory in cui ti trovi attualmente. Come puoi vedere, il passaggio a /ETC non ha funzionato in quanto non esiste tale directory. Il passaggio invece alla directory /etc esistente, è riuscito.
Creare Directory
Il comando mkdir viene utilizzato per creare directory. Creiamo una nuova directory nella nostra directory home:
$ cd ~
$ pwd
/home/user
$ ls
Desktop Documents Downloads
$ mkdir linux_lezione6
$ ls
Desktop Documents Downloads linux_lezione6
$ cd linux_lezione6
$ pwd
/home/emma/linux_lezione6
Per la durata di questa lezione, tutti i comandi avranno luogo all’interno di questa directory o in una delle sue sottodirectory. Per tornare facilmente alla directory linux_lezione6 da qualsiasi altra posizione nel file system, è possibile utilizzare il comando:
cd ~/linux_lezione6
La shell interpreta il carattere ~ come directory home. Quando ti trovi nella directory della lezione, crea alcune altre directory che utilizzeremo per gli esercizi. Puoi aggiungere tutti i nomi di directory, separati da spazi, a mkdir:
$ mkdir creating moving copying/files copying/directories deleting/directories deleting/files globs
mkdir: cannot create directory ‘copying/files’: No such file or directory
mkdir: cannot create directory ‘copying/directories’: No such file or directory
mkdir: cannot create directory ‘deleting/directories’: No such file or directory
mkdir: cannot create directory ‘deleting/files’: No such file or directory
$ ls
creating globs moving
Notare il messaggio di errore e che sono stati creati solo creating, moving e globs. Le directory copying ed deleting non esistono ancora.
mkdir, per impostazione predefinita, non creerà una directory all’interno di una directory che non esiste. L’opzione -p o –parents indica a mkdir di creare directory principali se non esistono. Proviamo lo stesso comando di prima con l’opzione -p:
$ mkdir -p creating moving copying/files copying/directories deleting/directories deleting/files globs
Ora non riceviamo alcun messaggio di errore. Vediamo quali directory esistono ora:
$ find
.
./creating
./moving
./globs
./copying
./copying/files
./copying/directories
./deleting
./deleting/directories
./deleting/files
Il programma find viene solitamente utilizzato per cercare file e directory, ma senza alcuna opzione, ti mostrerà un elenco di tutti i file, directory e sottodirectory della tua directory corrente.
Creare File
In genere, i file vengono creati dai programmi che funzionano con i dati memorizzati negli stessi file. È possibile creare un file vuoto usando il comando touch. Se lanci touch su un file esistente, il contenuto del file non verrà modificato, ma il timestamp di modifica dei file verrà aggiornato. Esegui il comando seguente per creare alcuni file nella directory globs:
$ touch globs/question1 globs/question2012 globs/question23 globs/question13 globs/question14
$ touch globs/star10 globs/star1100 globs/star2002 globs/star2013
Ora verifichiamo che tutti i file esistano nella directory globs:
$ cd globs
$ ls
question1 question14 question23 star1100 star2013
question13 question2012 star10 star2002
Notate come touch ha creato i file? È possibile visualizzare il contenuto di un file di testo con il comando cat. Provalo su uno dei file che hai appena creato:
$ cat question14
Poiché touch crea file vuoti, non si dovrebbe ottenere alcun output. È possibile invece utilizzare echo con “>” per creare semplici file di testo con un contenuto. Proviamolo:
$ echo hello > question15
$ cat question15
hello
echo visualizza il testo sulla riga di comando. Il carattere “>” indica alla shell di scrivere l’output del comando nel file specificato anziché nel terminale. Questo porta all’output di echo, (“hello” in questo caso) che viene scritto nel file question15.
Fai attenzione quando usi “>” su un file esistente, il file verrà sovrascitto!.
Rinominare File
I file vengono spostati e rinominati con il comando mv. Imposta la tua directory di lavoro sulla directory moving:
$ cd ~/linux_lezione6/moving
Crea alcuni file con cui esercitarti. Ormai, dovresti già avere familiarità con questi comandi:
$ touch file1 file22
$ echo file3 > file3
$ echo file4 > file4
$ ls
file1 file22 file3 file4
Supponiamo che file22 sia un refuso e che il nome corretto debba essere file2. Risolvilo con il comando mv. Quando si rinomina un file, il primo argomento è il nome corrente, il secondo è il nuovo nome:
$ mv file22 file2
$ ls
file1 file2 file3 file4
Fai attenzione con il comando mv. Se si rinomina un file con il nome di un file esistente, lo sovrascriverà. Proviamo questo con file3 e file4:
$ cat file3
file3
$ cat file4
file4
$ mv file4 file3
$ cat file3
file4
$ ls
file1 file2 file3
Notare come il contenuto di file3 sia ora file4. Conviene utilizzare l’opzione -i per fare in modo che mv ti chieda se stai per sovrascrivere un file esistente. Proviamolo:
$ touch file4 file5
$ mv -i file4 file3
mv: overwrite ‘file3’? y
Spostare File
I file vengono spostati da una directory all’altra con il comando mv. Creiamo alcune directory per poi spostare alcuni file:
$ cd ~/linux_lezione6/moving
$ mkdir dir1 dir2
$ ls
dir1 dir2 file1 file2 file3 file5
Sposta il file1 dentro dir1:
$ mv file1 dir1
$ ls
dir1 dir2 file2 file3 file5
$ ls dir1
file1
Nota come l’ultimo argomento di mv sia la directory di destinazione. Ogni volta che l’ultimo argomento di mv è una directory, i file vengono spostati in essa. È possibile specificare più file in un singolo comando mv:
$ mv file2 file3 dir2
$ ls
dir1 dir2 file5
$ ls dir2
file2 file3
È anche possibile utilizzare mv per spostare e rinominare le directory. Rinomina dir1 in dir3
$ ls
dir1 dir2 file5
$ ls dir1
file1
$ mv dir1 dir3
$ ls
dir2 dir3 file5
$ ls dir3
file1
Cancellare File e Directory
Il comando rm può eliminare file e directory, mentre il comando rmdir può eliminare solo directory. Puliamo la directory moving eliminando file5:
$ cd ~/linux_essentials-2.4/moving
$ ls
dir2 dir3 file5
$ rmdir file5
rmdir: failed to remove ‘file5’: Not a directory
$ rm file5
$ ls
dir2 dir3
Di default rmdir può cancellare solo directory vuote, quindi abbiamo dovuto usare rm per cancellare un file normale. Prova a eliminare la directory deleting:
$ cd ~/linux_lezione6/
$ ls
copying creating deleting globs moving
$ rmdir deleting
rmdir: failed to remove ‘deleting’: Directory not empty
$ ls -l deleting
total 0
drwxrwxr-x. 2 emma emma 6 Mar 26 14:58 directories
drwxrwxr-x. 2 emma emma 6 Mar 26 14:58 files
Per impostazione predefinita, rmdir rifiuta di eliminare una directory che non è vuota. Utilizziamo rmdir per rimuovere una delle sottodirectory vuote della directory deleting:
$ ls -a deleting/files
. ..
$ rmdir deleting/files
$ ls -l deleting
directories
Eliminare un gran numero di file o directory con molte sottodirectory può sembrare noioso, ma in realtà è facile. Per impostazione predefinita, rm funziona solo su file normali. L’opzione -r viene utilizzata per ignorare questo comportamento. Fai attenzione, il comando rm -r può essere molto pericoloso. Quando si utilizza l’opzione -r, rm non solo cancellerà tutte le directory, ma tutto ciò che si trova all’interno di quella directory, comprese le sottodirectory e il loro contenuto. Guarda tu stesso come funziona rm -r:
$ ls
copying creating deleting globs moving
$ rm deleting
rm: cannot remove ‘deleting’: Is a directory
$ ls -l deleting
total 0
drwxrwxr-x. 2 emma emma 6 Mar 26 14:58 directories
$ rm -r deleting
$ ls
copying creating globs moving
Notate come la directory deleting è stata cancellata, nonostante non fosse vuota. Come mv, rm ha un’opzione -i per richiederti prima una conferma. Utilizziamo quindi rm -ri per rimuovere, in sicurezza, la directory moving e tutte le sottodirectory contenute:
$ rm -ri moving
rm: descend into directory ‘moving’? y
rm: descend into directory ‘moving/dir2’? y
rm: remove regular empty file ‘moving/dir2/file2’? y
rm: remove regular empty file ‘moving/dir2/file3’? y
rm: remove directory ‘moving/dir2’? y
rm: descend into directory ‘moving/dir3’? y
rm: remove regular empty file ‘moving/dir3/file1’? y
rm: remove directory ‘moving/dir3’? y
rm: remove directory ‘moving’? y
Copiare file e directory
Il comando cp viene utilizzato per copiare file e directory. Copia alcuni file nella directory copying:
$ cd ~/linux_lezione6/copying
$ ls
directories files
$ cp /etc/nsswitch.conf files/nsswitch.conf
$ cp /etc/issue /etc/hostname files
Se l’ultimo argomento è una directory, cp creerà una copia degli argomenti precedenti all’interno della directory. Come mv, è possibile specificare più file contemporaneamente, purché la destinazione sia una directory. Quando entrambi gli operandi di cp sono file ed esistono entrambi, cp sovrascrive il secondo file con una copia del primo file. Verifichiamolo sovrascrivendo il file issue con il file hostname:
$ cd ~/linux_lezione6/copying/files
$ ls
hostname issue nsswitch.conf
$ cat hostname
mycomputer
$ cat issue
Debian GNU/Linux 9 \n \l
$ cp hostname issue
$ cat issue
mycomputer
Ora proviamo a creare una copia della directory files all’interno della directory directories:
$ cd ~/linux_essentials-2.4/copying
$ cp files directories
cp: omitting directory ‘files’
Come puoi vedere, cp di default funziona solo su singoli file. Per copiare una directory, utilizzare l’opzione -r. Tieni presente che l’opzione -r farà sì che cp copi anche il contenuto della directory che stai copiando:
$ cp -r files directories
$ find
.
./files
./files/nsswitch.conf
./files/fstab
./files/hostname
./directories
./directories/files
./directories/files/nsswitch.conf
./directories/files/fstab
./directories/files/hostname
Avete notato che quando una directory esistente viene utilizzata come destinazione, cp crea una copia della directory di origine al suo interno? Se invece la destinazione non esiste, la creerà e la riempirà con il contenuto della directory di origine:
$ cp -r files files2
$ find
.
./files
./files/nsswitch.conf
./files/fstab
./files/hostname
./directories
./directories/files
./directories/files/nsswitch.conf
./directories/files/fstab
./directories/files/hostname
./files2
./files2/nsswitch.conf
./files2/fstab
./files2/hostname
Globbing – Caratteri speciali
Ciò che viene comunemente definito Globbing è un semplice linguaggio di corrispondenza dei modelli (pattern matching language). Le shell sui sistemi Linux usano questo linguaggio per fare riferimento a gruppi di file invece di applicare i comandi al file singolo. Il linguaggio utilizzato nelle shell di Linux (POSIX.1-2017) presenta i seguenti caratteri speciali:
- * Corrisponde a qualsiasi numero di qualsiasi carattere, inclusi i caratteri vuoti
- ? Corrisponde a un solo carattere (qualsiasi)
- [ ] Corrisponde a una classe di caratteri
Normalmente gli utenti linux utilizzano uno o più di questi caratteri per specificare più file invece di digitare il nome di ogni singolo file. Prendiamo come esempio i seguenti comandi:
$ cd ~/linux_lezione6/globs
$ ls
question1 question14 question2012 star10 star2002
question13 question15 question23 star1100 star2013
$ ls star1*
star10 star1100
$ ls star*
star10 star1100 star2002 star2013
$ ls star2*
star2002 star2013
$ ls star2*2
star2002
$ ls star2013*
star2013
La shell espande * in una qualsiasi quantità di un qualsiasi carattere, in questo caso ad esempio la shell interpreta star* per indicare qualsiasi cosa che inizia con star. Quando esegui il comando ls star*, ls non cerca il file star* ma cerca i file nella directory corrente che corrispondono al modello star* (incluso il solo star) e trasforma ogni file che corrisponde al modello in un argomento di ls. Il comando seguente
$ ls star*
corrisponde quindi a
$ ls star10 star1100 star2002 star2013
Vediamo invece come fare se vogliamo cercare il file “star*” (file non esistente)
$ ls star\* ls: cannot access star*: No such file or directory
Quando si precede un carattere con un \ si sta dicendo alla shell di non interpretarlo. Va utilizzato per fare in modo che la shell non interpreti i caratteri speciali visti prima.
Il carattere ? indica un qualsiasi carattere (uno solo a differenza di *). Prova i seguenti comandi per verificare di persona l’utilizzo del carattere “?”:
$ ls
question1 question14 question2012 star10 star2002
question13 question15 question23 star1100 star2013
$ ls question?
question1
$ ls question1?
question13 question14 question15
$ ls question?3
question13 question23
$ ls question13?
ls: cannot access question13?: No such file or directory
Le parentesi [ ] vengono utilizzate per abbinare intervalli o classi di caratteri. Le parentesi [ ] funzionano come nelle espressioni regolari POSIX, tranne che nella shell viene usato ^ invece di !. Facciamo un pò di esperimenti:
$ mkdir brackets
$ cd brackets
$ touch file1 file2 file3 file4 filea fileb filec file5 file6 file7
Gli intervalli tra le parentesi [ ] sono espressi usando il carattere –
$ ls
file1 file2 file3 file4 file5 file6 file7 filea fileb filec
$ ls file[1-2]
file1 file2
$ ls file[1-3]
file1 file2 file3
È possibile specificare più intervalli:
$ ls file[1-25-7]
file1 file2 file5 file6 file7
$ ls file[1-35-6a-c]
file1 file2 file3 file5 file6 filea fileb filec
Le parentesi quadre possono anche essere utilizzate per abbinare un set specifico di caratteri.
$ ls file[1a5]
file1 file5 filea
Puoi anche usare il carattere ^ come primo carattere per abbinare tutto tranne alcuni caratteri (ha il valore di negazione). Nell’esempio in basso si è abbinato ad ls tutti i file che iniziano con la parola file e terminano con un carattere diverso da a.
$ ls file[^a]
file1 file2 file3 file4 file5 file6 file7 fileb filec
L’ultima cosa che tratteremo in questa lezione sono le classi di caratteri. Per abbinare una classe di caratteri, va usato il costrutto [:classname:]. Ad esempio, per utilizzare la classe digit, che corrisponde ai numeri, dovresti fare qualcosa del genere:
$ ls file[[:digit:]]
file1 file2 file3 file4 file5 file6 file7
$ touch file1a file11
$ ls file[[:digit:]a]
file1 file2 file3 file4 file5 file6 file7 filea
$ ls file[[:digit:]]a
file1a
Il costrutto file[[:digit:]a] cerca i file il cui nome inizia per file e termina con un numero o con il carattere a
Le classi di caratteri supportate dipendono dalle impostazioni internazionali correnti. Le seguenti classi di caratteri sono presenti indipendentemente dall’impostazione selezionata:
- [:alnum:] – Lettere e numeri
- [:alpha:] – Lettere maiuscole o minuscole.
- [:blank:] – Spazi e tabulazioni
- [:cntrl:] – Caratteri Control (backspace, esc, etc.)
- [:digit:] – Numeri
- [:graph:] – Caratteri grafici (tutti i caratteri ad accezione di ctrl e gli spazi
- [:lower:] – Lettere minuscole (a-z)
- [:print:] – Caratteri stampabili (lettere, numeri, punteggiatura, spazi)
- [:punct:] – Punteggiatura
- [:space:] – Spazi bianchi (spazi, tabulazioni, interruzioni di riga, etc.)
- [:upper:] – Lettere maiuscole (A-Z)
- [:xdigit:] – Numeri esadecimali (0123456789abcdefABCDEF)