Panoramica del corso e shell
Motivazioni
Da informatici sappiamo che i computer offrono un grande aiuto a svolgere operazioni ripetitive. Nonostante ciò, troppo spesso ci dimentichiamo che questo può essere sfruttato anche nell’utilizzo del computer. Abbiamo a disposizione un’ampia gamma di strumenti che ci permettono di essere più produttivi e di risolvere problemi complessi che si incontrano durante il lavoro. Solitamente la maggior parte di noi usa solo marginalmente questi strumenti, magari facendo ciecamente copia e incolla da qualche sito.
Questa corso ha come obiettivo farvi scoprire questi strumenti e come usarli al meglio.
Vogliamo insegnarvi ad usare al massimo delle loro potenzialità gli strumenti che già usate, e mostrarvi nuovi strumenti da aggiungere al vostro bagaglio, nella speranza di avviarvi all’esplorazione (e magari implementazione) di altri strumenti. Questo è ciò che pensiamo sia il semestre mancante dalla maggior parte dei curriculum di informatica.
Struttura del corso
Il corso è diviso in 11 lezioni da un’ora, ognuna delle quali tratta un argomento specifico. Le lezioni sono indipendenti una dall’altra, ma daremo per scontato che avrete familiarità con gli argomenti delle lezioni precedenti. Online sono disponibili le note delle lezioni, ma durante le lezioni ci saranno alcune dimostrazioni interessanti che potrebbero non essere scritte nelle note. Le lezioni saranno registrate e pubblicate online.
Le lezioni saranno molto dense, nel tentativo di farvi scoprire molto nel poco tempo a disposizione. Per questo ogni lezione è corredata da degli esercizi che vi guideranno attraverso i punti chiave della lezione. Dopo ogni lezione ci sarà ricevimento, durante il quale risponderemo alle vostre domande. Se seguirai da remoto puoi farci le domande via mail (in inglese) a missing-semester@mit.edu.
Visto il poco tempo a disposizione, non potremmo coprire tutti gli strumenti allo stesso livello di completezza di un normale corso. Ove possibile vi indicheremo le risorse che potete usare per approfondire, ma se una cosa particolare vi stuzzica non esitate a chiederci altri materiali!
Argomento 1: La Shell
Cos’è shell?
I computer hanno molte interfacce attraverso cui dar loro comandi; carine interfacce grafiche, interfacce vocali, e anche attraverso la realtà virtuale/aumentata. Queste sono comode per l’80% dei casi d’uso, ma sono solitamente ristrette nelle loro potenzialità: non puoi premere un pulsante se non c’è o dare un comando vocale non programmato. Per usare al massimo gli strumenti che il tuo computer ti offre, dobbiamo usare la “vecchia” interfaccia, ovvero la shell.
In quasi tutte le piattaforme puoi avere accesso ad una shell, in un modo o nell’altro, e in molte puoi anche scegliere fra una vasta gamma di shell. Mentre possono cambiare in alcuni dettagli peculiari, il loro core è più o meno lo stesso: ti consentono di avviare programmi, passargli input, e analizzare il loro output, in una maniera semi-strutturata.
In questa lezione ci concentreremo sulla Bourne Again SHell (bash): una delle shell più usate, la cui sintassi è simile a quella di molte altre shell. Per aprire il prompt di una shell (dove andranno digitati i comandi), occorre un terminale. Molto probabilmente il tuo dispositivo ne ha già uno, altrimenti puoi facilmente installarlo.
Usare la shell
Quando avvii il terminale, vedrai un prompt che solitamente assomiglia a questo:
missing:~$
Questa è l’interfaccia testuale principale della shell. Ti dice che stai usando
la macchina di nome missing
e che la tua cartella di lavoro corrente è ~
(un
alias per indicare la cartella personale dell’utente, la home). Il dollaro
indica che sei un utente standard (non root, ne parleremo dopo). Dopo questo
prompt puoi digitare un comando, che verrà interpretato dalla shell. Il
comando più semplice che puoi dare è eseguire un programma:
missing:~$ date
Fri 10 Jan 2020 11:49:31 AM EST
missing:~$
Qui abbiamo eseguito il programma date
, che sorprendentemente stampa a video
la data e l’ora corrente. La shell dopodiché mostra un altro prompt in attesa
del prossimo comando. Possiamo anche eseguire comandi con argomenti:
missing:~$ echo hello
hello
In questo caso abbiamo detto alla shell di eseguire il programma echo
con
hello
come argomento. Il programma echo
semplicemente stampa a video i suoi
argomenti. La shell interpreta il comando e i suoi argomenti sperandoli con uno
spazio, e poi avvia il programma indicato dalla prima parola, passandogli come
argomento ogni parola successiva. Se vuoi passare un argomento che contiene uno
spazio o altri caratteri speciali (ad esempio la cartella “Foto personali”),
puoi sia racchiudere l’argomento fra virgolette singole ('Foto personali'
) o
doppie ("foto personali"
), oppure usare la sequenza di escape per lo spazio
(Foto\ personali
).
Ma come fa la shell a sapere dove si trovano i programmi?
La shell è un ambiente di programmazione, come Python o Ruby, e ha quindi le
variabili, le condizioni, i cicli e le funzioni (vedremo tutte queste cose nella
prossima lezione!). Quando avvi un comando nella shell, non stai facendo altro
che scrivere un piccolo pezzo di codice che la tua shell interpreta. Se alla
shell viene chiesto di eseguire un comando che non rientra nelle sue keyword,
allora legge una variabile d’ambiente chiamata $PATH
che elenca le cartelle
dove la shell deve cercare i programmi richiesti:
missing:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
missing:~$ type echo
/bin/echo
missing:~$ /bin/echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Quando avvii il comando echo
, la shell capisce che deve eseguire il programma
echo
e lo cerca attraverso le cartelle elencate (separate da :
) nella
variabile $PATH
. Quando lo trova lo esegue (assumendo che il file abbia i
permessi di esecuzione; ne parleremo più avanti). Possiamo trovare quale file
venga eseguito per un dato programma usando il comando type
(o il suo
antenato, which
). Possiamo eludere $PATH
inserendo direttamente il percorso
completo al file che vogliamo eseguire.
Muoversi nella shell
Un percorso nella shell è una lista di cartelle separate da /
(o \
su
Windows). Negli ambienti Unix-like (come GNU/Linux e macOS) il percorso /
rappresenta la radice (root) del file system, dentro la quale si trovano tutti
i file e le cartelle, mentre in Windows c’è una radice diversa per ogni
partizione (ad esempio C:\
). In questo corso supporremo che stiate usando un
file system Unix-like. Un percorso che iniza con /
è detto assoluto. Ogni
altro percorso è detto relativo. I percorsi relativi sono relativi all’attuale
cartella di lavoro, che può essere visualizzata con il comando pwd
(print
working directory) e cambiata con cd
(change directory). In un percorso .
si
riferisce alla cartella corrente, mentre ..
alla cartella padre:
missing:~$ pwd
/home/missing
missing:~$ cd /home
missing:/home$ pwd
/home
missing:/home$ cd ..
missing:/$ pwd
/
missing:/$ cd ./home
missing:/home$ pwd
/home
missing:/home$ cd missing
missing:~$ pwd
/home/missing
missing:~$ ../../bin/echo hello
hello
Notate come il prompt ci tenga informati sulla cartella in cui stiamo lavorando. Il prompt può essere personalizzato per mostrare molte altre informazioni utili, che andremo a vedere più avanti.
In generale, quando avviamo un programma, questo opera nella cartella corrente a meno che non specifichiamo diversamente. Ad esempio aprirà e/o creerà file nella cartella in cui ci troviamo quando viene eseguito.
Per vedere il contenuto di una cartella si usa il comando ls
:
missing:~$ ls
missing:~$ cd ..
missing:/home$ ls
missing
missing:/home$ cd ..
missing:/$ ls
bin
boot
dev
etc
home
...
ls
mostra il contenuto della cartella corrente o della cartella che gli viene
passata come argomento. La maggior parte dei comandi accetta dei flag e
opzioni (flag con un valore associato), che iniziano con un trattino, i quali
modificano il loro comportamento. Di solito, avviando un programma col flag -h
o --help
stamperà a video un riassunto dei flag e delle opzioni disponibili.
Per esempio ls --help
ci dirà:
-l use a long listing format
missing:~$ ls -l /home
drwxr-xr-x 1 missing users 4096 Jun 15 2019 missing
Questo ci darà molte informazioni in più riguardo ai file e alle cartelle
presenti. La d
all’inizio della riga ci dice che si tratta di una cartella
(directory). Poi ci sono 3 gruppi da 3 caratteri (rwx
) indicanti i permessi
che il proprietario del file (missing
), il gruppo proprietario (users
), e
tutti gli altri hanno rispettivamente sull’elemento. Un -
indica che il
permesso non è concesso. Nell’esempio solo il proprietario ha i permessi di
scrittura (w
riting; ovvero aggiungere/rimuovere file). Per accedere ad una
cartella bisogna avere i permessi di esecuzione (ex
ecute) sulla
stessa, nonché su tutte le cartelle genitore. Per elencare i file bisogna avere
i permessi di lettura (r
eading) sulla cartella. Per i file i permessi sono
più intuitivi. Notate come quasi tutti i file in /bin
siano eseguibili da
chiunque in modo che tutti possano avviare questi programmi.
Molti altri programmi utili da conoscere a questo punto sono mv
per rinominare
e spostare file, cp
per copiarli e mkdir
per creare cartelle.
Se vuoi più informazioni su un programma e i suoi argomenti, usa il programma
man
che fornisce i manuali della maggior parte dei programmi a linea di
comando. Per uscire dal manuale premi q
.
missing:~$ man ls
Connettere programmi
Nella shell i programmi hanno due canali (stream) principali che possono usare: quello di input e quello di output. Normalmente entrambi sono associati al terminale, ovvero la tua tastiera come input e lo schermo com output. Nonostante ciò è possibile reindirizzare questi stream.
Il modo più semplice per farlo è < file
e > file
. Questi ti permettono di
reindirizzare rispettivamente l’input e l’output di un programma su un file:
missing:~$ echo hello > hello.txt
missing:~$ cat hello.txt
hello
missing:~$ cat < hello.txt
hello
missing:~$ cat < hello.txt > hello2.txt
missing:~$ cat hello2.txt
hello
Nell’esempio abbiamo usato cat
, un programma che concat
ena file e li stampa
in output, prendendoli dai suoi argomenti o, se non ci sono, dal suo input.
Puoi usare anche >>
per aggiungere ad un file (>
cancella il file se
esiste già).
Inoltre l’operatore pipe (|
) permette di concatenare l’output di un
programma all’input del successivo:
missing:~$ ls -l / | tail -n1
drwxr-xr-x 1 root root 4096 Jun 20 2019 var
missing:~$ curl --head --silent google.com | grep --ignore-case content-length | cut --delimiter=' ' -f2
219
Vedremo meglio come usare le pipe nelle lezione sulla manipolazione dei dati.
Uno strumento versatile e potente
Nella maggior parte dei sistemi Unix-like c’è un utente speciale: root. Dovreste
averlo visto nei file elencati nell’esempio qua sopra. Questo utente è al di
sopra di quasi tutte le restrizioni e può creare, leggere, modificare e
cancellare ogni file del sistema. Per questo non bisogna entrare nel sistema
come root in quanto sarebbe facilissimo rompere qualcosa. Tuttavia a volte è
necessario agire come root, e si può fare usando il comando sudo
(super user,
root, do). Quando un programma ti avvisa che non hai i permessi per fare
qualcosa normalmente significa che necessiti di farlo tramite sudo, ma accertati
sempre che sia veramente il modo giusto di farlo.
Ad esempio per scrivere sul file system sysfs
(montato in /sys
) è necessario
essere root. sysfs
espone molti parametri del kernel come file, permettendone
una facile modifica. Nota che sysfs non è disponibile su Window e macOS
Per esempio la luminosità dello schermo di un portatile è disponibile su un file
chiamato brightness
all’interno di
/sys/class/backlight
Scrivendo su questo file si può cambiare al volo la luminosità. Istintivamente potreste fare una cosa simile:
$ sudo find -L /sys/class/backlight -maxdepth 2 -name '*brightness*'
/sys/class/backlight/thinkpad_screen/brightness
$ cd /sys/class/backlight/thinkpad_screen
$ sudo echo 3 > brightness
An error occurred while redirecting file 'brightness'
open: Permission denied
Questo errore potrebbe sorprendere più di qualcuno. Dopotutto abbiamo avviato il
comando come sudo
! Questa è una cosa importante da sapere sulla shell. Le
operazioni come |
, >
, <
sono eseguite dalla shell, non dal singolo
programma. echo
e gli altri non sono a conoscenza di |
: loro semplicemente
leggono e scrivono dai loro stream, qualsiasi siano. Nell’esempio sopra la
shell, che è autenticata come l’utente, tenta di aprire il file brightness in
scrittura, prima che venga impostato come output di sudo echo
, ma non può
farlo perché non è stata eseguita da root. Sapendo ciò possiamo risolvere così:
$ echo 3 | sudo tee brightness
Siccome è il comando tee
(che reindirizza il suo input sul file che prende
come argomento) ad aprire il file in scrittura, ed è avviato come root
, il
tutto funziona. Puoi controllare in questo modo tutto ciò che si trova sotto
/sys
, come lo stato di vari LED (il percorso varia da macchina a mancchina):
$ echo 1 | sudo tee /sys/class/leds/input6::scrolllock/brightness
Prossimi passi
A questo punto sai usare la shell abbastanza da poter completare semplici azioni. Dovresti essere in grado di muoverti fra le cartelle per trovare i file su cui lavorare e usare le funzionalità base dei programmi. Nella prossima lezione vedremo come completare e automatizzare task più complesse con la shell e molti programmi a linea di comando.
Esercizi
Tutte le lezioni in questo corso sono corredate da una serie di esercizi. Alcuni vi daranno alcuni compiti specifici da svolgere, mentre altri sono più liberi, come “prova ad usare i programmi X e Y”. Raccomandiamo fortemente di provali.
Non abbiamo scritto le soluzioni degli esercizi. Se ti blocchi in un punto particolare, scrivici pure una mail descrivendo cosa hai provato a fare e proveremo ad aiutarti.
- Per questo corso dovrai usare una shell Unix come Bash o ZSH. Se usi
GNU/Linux o macOS non dovrai fare nulla di speciale; se invece usi
Windows non potrai usare cmd.exe, né la PowerShell, bensì dovrai usare il
Windows Subsystem for Linux
o una macchina virtuale. Per essere sicuro di star usando una shell
appropiata puoi provare il comando
echo $SHELL
: se stampa qualcosa come/bin/bash
o/usr/bin/zsh
, questo significa che stai eseguendo il programma corretto. - Crea una nuova cartella chiamata
missing
dentro/tmp
. - Scopri cosa fa il comando
touch
. Ricorda cheman
è tuo amico. - Usa
touch
per creare un nuovo file chiamatosemester
nella cartellamissing
. - Scrivi quanto segue, una linea alla volta, nel file appena creato:
#!/bin/sh curl --head --silent https://missing.csail.mit.edu
La prima linea potrebbe essere complicata da inserire. Infatti in bash i commenti iniziano con
#
e!
ha un significato speciale anche fra doppie virgolette ("
). Per ovviare a questo problema vanno usate le singole virgolette ('
). Per più informazioni guarda il manuale di bash - Prova ad eseguire il file (digita
./semester
e premi invio). Cerca di capire, con l’aiuto dils
, perché non funzioni (suggerimento: controlla i bit dei permessi). - Avvia il comando avviando esplicitamente l’interprete
sh
passandogli il filesemester
come argomento (sh semester
). Perché così funzona e prima non andava? - Scopri come funziona il programma
chmod
. - Usa
chmod
per rendere possibile eseguire il comando./semester
evitando di dover eseguiresh semester
. Come fa la shell a capire che il file deve essere interpretato dash
? Guarda questa pagina riguardo gli shebang per maggiori informazioni. - Usa
|
e>
per scrivere la data di ultima modifica restituita dasemester
in un file chiamatoultima-modifica.txt
nella tua cartella home. - Scrivi un comando che legge la percentuale di batteria del tuo portatile o
la temperatura della CPU del tuo fisso, leggendole da
/sys
. Nota: se usi macOS non puoi fare questo esercizio.
Rilasciato sotto licenza CC BY-NC-SA.