Comandi di base della Shell Linux

Riassunto IA

La shell funge da interprete per l'esecuzione di comandi, gestendo l'interazione diretta con il sistema operativo attraverso la manipolazione di input, output e flussi di dati. Il prompt del terminale costituisce un'interfaccia contestuale essenziale, fornendo metadati critici su utente, host, directory di lavoro e privilegi di esecuzione correnti.

Immagine generata con IA
Immagine generata con IA

Comandi di base della Shell

Lavorare dalla shell significa comunicare direttamente con il sistema operativo attraverso istruzioni testuali. Un comando può essere un programma esterno (come ls), una funzione interna della shell, o una combinazione di più comandi collegati tra loro.

Quando digiti un comando, la shell lo interpreta, lo avvia e gestisce il suo input/output: il risultato può comparire a schermo, essere salvato su file o essere passato ad altri comandi tramite pipe. Conoscere questi strumenti, il loro significato, le possibilità e i limiti, è essenziale per lavorare in modo efficace e sicuro.

Anatomia del terminale

Prima di digitare qualsiasi comando, vale la pena capire cosa stai guardando. Quando apri un terminale, la prima cosa che vedi non è una pagina bianca, è un prompt, ovvero un invito della shell a ricevere istruzioni. Ogni elemento di quella riga ha un significato preciso.

Un prompt tipico su una distribuzione Linux si presenta così:

davide@ubuntu:~/progetti$

Pensala come una mappa: ti dice chi sei, dove sei e con quali permessi stai operando.

Gli elementi del prompt

davide   @   ubuntu   :   ~/progetti   $   _
  │      │     │      │       │        │   │
  │      │     │      │       │        │   └── Cursore
  │      │     │      │       │        └────── Modalità di esecuzione
  │      │     │      │       └─────────────── Directory corrente
  │      │     │      └─────────────────────── Separatore
  │      │     └────────────────────────────── Nome host
  │      └──────────────────────────────────── Separatore
  └─────────────────────────────────────────── Nome utente

Nome utente — Il nome dell'account con cui hai effettuato l'accesso. È importante perché determina quali file puoi leggere, scrivere o eseguire in base ai permessi del filesystem.

Nome host — Il nome della macchina su cui stai lavorando. Diventa fondamentale quando lavori su più server in remoto via SSH: ti impedisce di confonderti su quale macchina stai operando.

Directory corrente — Il percorso della directory in cui ti trovi in quel momento. La tilde (~) è una scorciatoia per la tua home directory (es. /home/davide). Questa informazione cambia ogni volta che usi cd.

Modalità di esecuzione — Il simbolo finale è probabilmente il più importante:

Simbolo Significato Quando compare
$ Utente normale Operazioni quotidiane, permessi limitati
# Utente root (superutente) Accesso completo al sistema

Attenzione: Quando vedi #, stai operando come root: hai permessi illimitati. Qualsiasi comando eseguito in questa modalità può modificare o danneggiare file di sistema senza alcuna protezione. Usa l'accesso root solo quando strettamente necessario, e preferisci sudo per i singoli comandi che lo richiedono.

Cursore — Il trattino lampeggiante (o il blocco, a seconda della configurazione del terminale) che segue il prompt indica che la shell è in attesa del tuo input. Se il cursore non compare o il prompt non ritorna dopo aver eseguito un comando, significa che la shell è ancora occupata, o che il processo è in attesa di input da tastiera.

Il prompt è personalizzabile

Quello che hai visto sopra è il formato più comune, ma il prompt può avere forme molto diverse. Alcune shell e configurazioni mostrano informazioni aggiuntive come il ramo Git corrente, l'ambiente virtuale Python attivo, o l'ora dell'ultimo comando. Tutto questo è controllato dalla variabile d'ambiente PS1 (e PS2 per i prompt di continuazione). Non devi modificarla ora, ma sapere che esiste ti aiuta a capire perché prompt su macchine diverse possono sembrare così diversi.

Anatomia di un comando

Ogni comando segue una struttura formale precisa:

<programma> [-opzione <valore>] <parametro1> <parametro2> …
  • Programma — il nome del comando da eseguire (es. ls, cp, grep).
  • Opzioni — modificano il comportamento rispetto alle impostazioni di default. Si identificano con - (forma breve) o -- (forma lunga) e possono richiedere un valore associato (es. -n 5 o --lines=5).
  • Flag — opzioni booleane senza valore associato: la loro semplice presenza attiva un comportamento (es. -r, -a, -i).
  • Parametri — i valori posizionali su cui il comando opera (percorsi, nomi file, stringhe). Il numero di parametri richiesti varia da comando a comando.

Per conoscere tutte le opzioni e i parametri disponibili per qualsiasi programma, usa sempre man <programma>.

Esempio scomposto

ls -l -a --color=always /home/davide
Parte Tipo Significato
ls Programma Il comando da eseguire
-l Flag Formato lungo
-a Flag Include file nascosti
--color=always Opzione Forza l'output colorato
/home/davide Parametro La directory da listare

I comandi fondamentali

pwd — Dove mi trovo?

pwd sta per print working directory e mostra il percorso assoluto della directory in cui ti trovi in quel momento.

$ pwd
/home/davide/progetto

Quando usarlo: ogni volta che non sei sicuro della tua posizione nel filesystem, soprattutto dopo una serie di cd o prima di eseguire comandi che operano su percorsi relativi.

Perché sceglierlo: è il modo più diretto per evitare errori di percorso. Sapere dove sei prima di cancellare o modificare file può fare la differenza tra un'operazione riuscita e un disastro.

ls — Cosa c'è qui dentro?

ls elenca il contenuto di una directory. Senza opzioni mostra solo i nomi; con le opzioni giuste fornisce dettagli su permessi, proprietario, dimensione e timestamp.

$ ls -la /home/davide
Opzione
-l Formato lungo con dettagli (permessi, dimensione, data)
-a Include i file nascosti (quelli che iniziano con .)
-h Dimensioni leggibili (es. 4.2K invece di 4312)
-t Ordina per data di modifica

Quando usarlo: per esplorare una directory, verificare la presenza di file, controllare i permessi o capire cosa è stato modificato di recente.

cd — Spostati nel filesystem

cd (change directory) cambia la directory di lavoro corrente della shell.

$ cd /etc          # percorso assoluto
$ cd ~/progetti    # ~ è la shortcut per la home
$ cd ..            # sale di un livello
$ cd -             # torna alla directory precedente

Quando usarlo: prima di operare su file in una directory diversa da quella corrente — editare, copiare, eseguire script.

Perché sceglierlo: lavorare dalla directory giusta consente di usare percorsi relativi più brevi. Le scorciatoie (~, -, ..) velocizzano molto la navigazione una volta che le si conosce.

touch — Crea un file o aggiorna i timestamp

touch crea un file vuoto se non esiste; se esiste già, aggiorna la sua data/ora di modifica senza toccare il contenuto.

$ touch file.txt
$ touch src/index.ts

Quando usarlo: per creare rapidamente file, per forzare la ricompilazione in build system basati su timestamp, o per aggiornare i metadati di un file.

Perché sceglierlo: è non distruttivo — non sovrascrive mai il contenuto esistente.

mkdir -p — Crea directory (anche annidate)

mkdir crea una o più directory. L'opzione -p crea anche tutte le directory intermedie mancanti, senza errori se esistono già.

$ mkdir -p progetto/src/components

Senza -p, se progetto/src non esiste il comando fallisce. Con -p, crea l'intera struttura in un colpo solo.

Quando usarlo: ogni volta che devi creare strutture di cartelle annidate, specialmente in script che vuoi poter rieseguire senza problemi.

Perché sceglierlo: rende gli script idempotenti — possono essere eseguiti più volte senza effetti collaterali indesiderati.

cp -r e mv — Copia e sposta

cp copia file e, con -r, intere directory in modo ricorsivo. mv sposta o rinomina file e directory.

$ cp -r src/ backup/src/      # copia ricorsiva
$ mv report.txt archivio/     # sposta
$ mv vecchio_nome nuovo_nome  # rinomina

Quando usare cp: quando vuoi duplicare mantenendo l'originale intatto.

Quando usare mv: quando basta spostare o rinominare. All'interno dello stesso filesystem, mv è molto più efficiente di cp + rm perché non copia fisicamente i dati — aggiorna solo i metadati del filesystem.

rm -r / rm -f — Rimuovi file e directory

rm elimina file in modo definitivo (non finiscono nel cestino). Con -r rimuove ricorsivamente directory intere; con -f forza l'operazione senza chiedere conferma.

$ rm file.txt          # rimuove un singolo file
$ rm -r dist/          # rimuove la directory dist/ e tutto il suo contenuto
$ rm -i *.log          # chiede conferma per ogni file (consigliato)

Attenzione: rm -rf / cancella l'intero filesystem se eseguito con i privilegi giusti. Verifica sempre il percorso prima di usare -rf.

Quando usarlo: per pulire file o directory non più necessari, in script di build o deploy.

Consiglio: in caso di dubbio usa -i per ricevere una conferma interattiva prima di ogni eliminazione.

cat e less — Leggi il contenuto di un file

cat stampa il contenuto di un file direttamente nel terminale. less apre un visualizzatore interattivo che permette di scorrere, cercare e navigare.

$ cat config.json          # output immediato, tutto in una volta
$ less /var/log/syslog     # visualizzazione paginata e navigabile

In less: usa le frecce o j/k per scorrere, /termine per cercare, q per uscire.

Quando usare cat: per file brevi o per concatenare più file in pipeline (cat a.txt b.txt | sort).

Quando usare less: per file lunghi come log di sistema — eviti di intasare il terminale con migliaia di righe.

man — Il manuale integrato

man (manual) apre la pagina di documentazione ufficiale di un comando, direttamente nel terminale. Ogni pagina descrive scopo, sintassi, opzioni e, spesso, esempi d'uso.

$ man ls       # apre il manuale di ls
$ man cp       # apre il manuale di cp

La navigazione in man usa le stesse scorciatoie di less: frecce o j/k per scorrere, /termine per cercare, q per uscire.

Quando usarlo: ogni volta che non ricordi un'opzione specifica o vuoi capire il comportamento esatto di un comando senza cercare su internet. È la fonte più affidabile perché è sempre aggiornata alla versione installata sul tuo sistema.

Perché sceglierlo: man non richiede connessione, non ha pubblicità e non ti porta su Stack Overflow. È lento da leggere all'inizio, ma imparare a navigarlo è un investimento che ripaga nel tempo.

💡 Se vuoi una versione più concisa, prova man -k termine per cercare tra tutte le pagine di manuale che menzionano una parola chiave, oppure comandi come tldr (da installare separatamente) per riassunti pratici e orientati agli esempi.

clear — Pulisci lo schermo

clear svuota il terminale rimuovendo tutto l'output precedente, riportando il prompt in cima allo schermo.

$ clear

In alternativa, la scorciatoia da tastiera Ctrl + L produce lo stesso effetto senza dover digitare nulla.

Quando usarlo: quando lo schermo è affollato di output e vuoi ricominciare da una vista pulita, oppure prima di eseguire un comando il cui output vuoi leggere senza distrazioni.

Perché sceglierlo: non cancella la cronologia dei comandi (history rimane intatta) né termina processi in esecuzione — è puramente visivo. Se vuoi scorrere l'output precedente dopo un clear, nella maggior parte dei terminali puoi farlo con la rotella del mouse o con Shift + PgUp.

exit — Chiudi la sessione

exit termina la sessione della shell corrente. Se stai lavorando in un terminale normale, chiude la finestra o la scheda. Se sei connesso via SSH a un server remoto, disconnette la sessione remota riportandoti alla shell locale.

$ exit

Puoi ottenere lo stesso risultato con la scorciatoia Ctrl + D, che invia il segnale di fine input alla shell.

Quando usarlo: per chiudere sessioni SSH in modo pulito, per uscire da una subshell avviata manualmente, o semplicemente per terminare il lavoro nel terminale.

Perché sceglierlo: chiudere una sessione con exit è più corretto che chiudere brutalmente la finestra del terminale, soprattutto su connessioni remote: assicura che i processi associati alla sessione vengano terminati correttamente.

Canali di comunicazione di un comando

Ogni comando ha a disposizione tre canali di comunicazione con il resto del sistema:

Canale Nome Descrizione
stdin Standard input L'ingresso del programma. Di default è collegato alla tastiera.
stdout Standard output L'uscita principale del programma. Di default viene mostrata nel terminale.
stderr Standard error L'uscita dedicata agli errori e ai messaggi di stato. Tenuta su un canale separato per evitare che si mescoli con l'output normale. Di default appare anch'essa nel terminale.

Separare stdout e stderr è una scelta progettuale importante: permette di filtrare, reindirizzare o loggare errori e output in modo indipendente, senza che si contaminino a vicenda.

Redirezione dell'output

La shell permette di collegare i canali di comunicazione tra comandi e file, costruendo catene di elaborazione anche complesse. Queste operazioni si chiamano redirezioni.

Sinstassi Effetto
comando > file Scrive stdout nel file (sovrascrive se esiste)
comando >> file Appende stdout al file (non sovrascrive)
comando < file Usa il file come stdin del comando
comando 2> file Scrive stderr nel file
comando1 | comando2 Trasforma l'output del primo comando (stdout) comando1 in input (stdin) del secondo comando comando2

Esempi pratici

# Salva la lista dei file in un log
$ ls -la > lista_file.txt

# Appende nuovi risultati senza sovrascrivere
$ ls ~/downloads >> lista_file.txt

# Filtra solo gli errori in un file separato
$ make 2> errori.log

# Concatena due file e cerca una stringa
$ cat a.txt b.txt | grep "TODO"

La pipe (|) è uno degli strumenti più potenti della shell: permette di comporre programmi semplici in pipeline sofisticate, dove l'output di uno diventa l'input del successivo.

Comandi di elaborazione dell'output

Questi comandi sono progettati per trasformare, filtrare e analizzare dati testuali. Lavorano spesso in combinazione tramite pipe, e il loro punto di forza è proprio la componibilità: incatenati insieme, permettono di estrarre esattamente le informazioni che servono da flussi di dati anche molto grandi.

echo — Stampa una stringa

echo scrive una stringa su stdout. Semplice, ma molto utile in script e pipeline.

$ echo "Ciao mondo"
Ciao mondo

$ echo -n "senza newline"   # non va a capo alla fine
$ echo -e "\e[36;1mTesto ciano grassetto\e[0m"   # interpreta escape ANSI
Opzione
-n Non aggiunge il carattere di newline finale
-e Interpreta i caratteri di escape (es. colori ANSI, \t, \n)

Quando usarlo: per stampare messaggi in script, per passare stringhe a pipeline, o per testare rapidamente l'output di variabili d'ambiente (echo $PATH).

Perché sceglierlo: è universalmente disponibile e non ha dipendenze. Con -e permette anche di formattare l'output con colori e stili (vedi man console_codes per i codici ANSI).

head e tail — Prime e ultime righe

head mostra le prime righe di un file o di uno stream; tail mostra le ultime. Per default entrambi mostrano 10 righe.

$ head -n 5 access.log      # prime 5 righe
$ tail -n 20 error.log      # ultime 20 righe
$ tail -f /var/log/syslog   # segue il file in tempo reale (live)
Opzione
-n <numero> Specifica il numero di righe da mostrare

Quando usarli: head per ispezionare l'intestazione di un file (es. CSV con colonne); tail per leggere le righe più recenti di un log. tail -f è particolarmente utile per monitorare log applicativi in tempo reale.

Perché sceglierli: evitano di caricare l'intero file quando serve solo una porzione. Su file di log da gigabyte, la differenza è sostanziale.

grep — Cerca nel testo

grep (General Regular Expression Print) cerca righe che corrispondono a un pattern all'interno di file o stream. Restituisce solo le righe che contengono la corrispondenza.

$ grep "errore" app.log               # cerca la stringa "errore"
$ grep -i "warning" app.log           # case insensitive
$ grep -n "TODO" src/main.ts          # mostra il numero di riga
$ grep -c "404" access.log            # conta le righe corrispondenti
$ cat app.log | grep -i "error"       # in pipeline
Opzione
-i Ignora maiuscole/minuscole
-n Precede ogni riga con il suo numero
-c Restituisce solo il conteggio delle righe corrispondenti

Quando usarlo: per filtrare log, cercare occorrenze di una stringa in un file, o come filtro in una pipeline (comando | grep "pattern").

Perché sceglierlo: è lo strumento standard per la ricerca testuale su stream e file. Supporta anche le espressioni regolari, che aprono possibilità di ricerca molto più avanzate della semplice stringa fissa.

wc — Conta righe, parole e caratteri

wc (Word Count) conta righe, parole e caratteri di un file o stream.

$ wc file.txt              # righe, parole e caratteri
$ wc -l *.log              # conta solo le righe di ogni file .log
$ cat file.txt | wc -w     # conta le parole via pipe
Opzione
-l Conta solo le righe
-w Conta solo le parole
-m Conta solo i caratteri

Quando usarlo: per sapere quante righe ha un file di log, quante voci contiene un CSV, o quante occorrenze ha restituito un grep.

Perché sceglierlo: è veloce e componibile. grep "errore" app.log | wc -l risponde in un colpo solo a "quanti errori ci sono nel log?".

sort — Ordina le righe

sort riordina le righe di un file o stream secondo la regola specificata. Di default ordina lessicograficamente.

$ sort nomi.txt                  # ordine alfabetico
$ sort -r nomi.txt               # ordine inverso
$ sort -g numeri.txt             # ordine numerico
$ sort -R lista.txt              # ordine casuale
$ cat log.txt | sort -f          # case insensitive via pipe
Opzione
-f Ignora maiuscole/minuscole
-g Ordine numerico
-d Ordine alfabetico (dizionario, ignora punteggiatura)
-r Ordine inverso
-R Ordine casuale

Quando usarlo: per ordinare output prima di confrontarlo, per preparare dati per uniq, o per trovare rapidamente il valore massimo/minimo in una lista numerica.

Perché sceglierlo: è spesso il passaggio intermedio necessario in una pipeline prima di elaborazioni successive — sort + uniq è una combinazione classica.

uniq — Rimuovi o conta i duplicati

uniq (UNIQue) opera su righe adiacenti identiche: le rimuove, le conta o le filtra. Per funzionare correttamente su file non ordinati, va quasi sempre preceduto da sort.

$ sort lista.txt | uniq          # rimuove i duplicati
$ sort lista.txt | uniq -c       # conta le occorrenze di ogni valore
$ sort lista.txt | uniq -u       # mostra solo i valori univoci
$ sort lista.txt | uniq -d       # mostra solo i valori duplicati
Opzione
-i Ignora maiuscole/minuscole
-c Precede ogni riga con il numero di occorrenze
-u Mostra solo le righe che appaiono una volta sola
-d Mostra solo le righe che appaiono più di una volta

Quando usarlo: per deduplicare liste, per trovare valori ripetuti in un log, o per costruire un conteggio delle frequenze (sort | uniq -c | sort -rg restituisce una classifica delle occorrenze).

Perché sceglierlo: in combinazione con sort, grep e wc copre la maggior parte dei casi d'uso di analisi testuale rapida senza bisogno di script complessi.

Come scegliere il comando giusto

La scelta dipende da tre fattori principali:

  • Scopo (Identifica l'azione): leggere, copiare, spostare, eliminare. Scegli il comando che fa esattamente quello e niente di più.
  • Efficienza: mv è più veloce di cp + rm per spostamenti sullo stesso filesystem. Conoscere queste differenze evita operazioni inutili.
  • Sicurezza: Preferisci comandi che richiedono conferma (rm -i) per operazioni distruttive. In uno script, verifica sempre i percorsi prima di eseguire cancellazioni.

Commenti