Le subshell sono shell che apriamo dentro una shell già aperta. Detta così sembra una cosa strana, ma se ne parla relativamente poco e invece è utilissima nella pratica quotidiana. In questo articolo vediamo una subshell in azione, la sostituzione di comando, la visibilità delle variabili e come usarle per lanciare lavori in background e in parallelo.
Una subshell semplice
Una subshell si apre con le parentesi tonde. Dentro mettiamo i comandi che vogliamo eseguire, per esempio pwd e ls:
(pwd; ls)
Tutti i comandi all’interno vengono eseguiti, uno dopo l’altro, e l’output è quello che ci aspettiamo: prima il percorso e poi l’elenco dei file. Detto così non sembra molto utile, ma è comoda perché ci permette di mettere diversi comandi in fila e lanciarli come se fossero uno solo.
La sostituzione di comando
L’uso più comune delle subshell è la sostituzione di comando: si assegna a una variabile, in uno script o anche a riga di comando, il valore di ritorno, cioè l’output, di un comando. Si scrive con il dollaro e le parentesi tonde:
percorso=$(pwd)
echo $percorso
L’output è la cartella corrente, per esempio:
/home/utente
In questo modo eseguiamo un comando, catturiamo il suo output e lo mettiamo in una variabile, o comunque ci facciamo delle cose sopra.
La visibilità delle variabili
Qui bisogna stare attenti, perché le variabili hanno uno scope un po’ strano. Una subshell vede le variabili della shell genitore, ma se le modifica, le modifiche restano locali alla subshell. Dichiariamo una variabile e poi modifichiamola dentro una subshell:
test=10
( echo $test; test=20; echo $test )
Dentro vediamo prima 10 e poi 20:
10
20
Ma se da fuori, dalla shell genitore, leggiamo di nuovo la variabile:
echo $test
L’output è ancora:
10
Non fate confusione con la visibilità delle variabili: è molto importante per evitare errori.
Una subshell in background
Possiamo mandare in background un’intera subshell, per esempio se ci mettiamo dentro dei comandi che richiederanno molto tempo. Un esempio un po’ stupido ma chiaro: dormiamo per dieci secondi e poi scriviamo qualcosa, il tutto con la e commerciale finale che manda tutto in background.
( sleep 10; echo finito ) &
Il processo va in background e il terminale resta libero. Dopo dieci secondi compare la parola:
finito
Parallelizzare I comandi
Le subshell servono anche a eseguire i comandi in parallelo. Prepariamo tre script, che chiamiamo sleep1.sh, sleep2.sh e sleep3.sh. Il primo è questo:
#!/bin/bash
sleep 10
echo "finito"
Il secondo e il terzo sono identici, ma con sleep 20 e sleep 30. Li rendiamo eseguibili:
chmod +x sleep1.sh sleep2.sh sleep3.sh
E li lanciamo tutti insieme in background:
./sleep1.sh & ./sleep2.sh & ./sleep3.sh &
I tre processi girano in parallelo e li vediamo finire uno alla volta, a dieci, venti e trenta secondi dall’avvio:
finito
finito
finito
Nel frattempo il terminale è libero e possiamo dare altri comandi mentre le subshell lavorano per noi.
Chiusura
Questo è tutto sulle subshell: parentesi tonde per raggruppare comandi, sostituzione di comando per catturare l’output, variabili che si possono leggere ma non modificare per il genitore, e la e commerciale per lavorare in background e in parallelo. Aprite la vostra Linux box e giocateci un po’.
Link e risorse
- il video su YouTube
- esempi e comandi della puntata su GitHub
- Manuale di Bash (man page) — in italiano
- SubShell, Wooledge wiki — quando nasce una subshell e cosa eredita
- Command substitution, Wooledge wiki — la sostituzione di comando
- Shell, Wikipedia — in italiano
Sostieni il canale
PER SOSTENERE IL CANALE BASTANO UN LIKE E UN’ISCRIZIONE!
ma se vuoi offrirmi un caffè, mi aiuterà a rimanere sveglio mentre registro i video 😁☕
clicca qui per scoprire come https://buymeacoffee.com/thelinuxnerd
questi link sono affiliati Amazon, acquistando i libri che ti consiglio sostieni il canale!
