Quando si esegue uno script Bash ci sono due modalità principali da impiegare, che hanno conseguenze diverse sull’ambiente della shell.
Sommario
1. Esecuzione diretta (./script.sh
)
- Lo script viene eseguito in un nuovo processo figlio della shell corrente.
- È equivalente a lanciare:
sh script.sh
oppurebash script.sh
(a seconda dello shebang in testa allo script). - Le variabili di ambiente create o modificate nello script non influenzano la shell madre: al termine del processo figlio vanno perse.
- Lo script può però leggere le variabili esportate (
export VAR=valore
) dalla shell che lo ha invocato.
Quindi può solo leggere le variabili di ambiente della shell madre ma non può scriverle.
2. Sourcing (source script.sh
oppure . script.sh
)
- Lo script viene eseguito nella shell corrente, senza avviare un processo figlio.
- Tutte le modifiche a variabili, alias, funzioni o al
PATH
rimangono attive anche dopo l’esecuzione. - È l’approccio necessario per script che devono modificare l’ambiente, ad esempio gli script
activate
dei virtual environment Python. Infatti è qui che ho trovato questo comando: dovevo fare partire un ambiente virtuale Python isolato che uso per fare esperimenti con Python.
Esempio di comportamento
# file: test.sh MYVAR="ciao" echo "Dentro lo script: $MYVAR"
- L’output del programma bash è
bash test.sh
:Dentro lo script: ciao
ma poi se vado a vedere il contenuto della variabile di ambiente (a esecuzuone terminata) non trovo nulla:echo $MYVAR # (vuoto)
- Se invece uso source e non bash
source test.sh
:Dentro lo script: ciao
e poi tovo anche la variabile di ambiente nella shell madre:echo $MYVAR # ciao
Variabili esportate
C’è una distinzione importante tra variabili normali e variabili esportate: se dalla shell definsco due variabili di ambiente in questi due modi diversi:
$ VAR1="pippo" # variabile locale alla shell $ export VAR2="pluto" # variabile esportata
poi se andrò a lanciare lo script che mi stampa le due variabili
# contenuto dello script.sh echo $VAR1 echo $VAR2
il risultato sarà il seguente
$ ./pyvenv.sh PLUTO
lo script vedrà solo VAR2
(perché è stata esportata) mentre non vedrà VAR1
(che è locale alla shell).
Nessuna delle due variabili può essere “restituita indietro” dallo script, a meno di usare source
.
Quindi, riassumendo:
./script.sh
: nuovo processo → legge solo variabili esportate → modifiche non persistono.source script.sh
: stessa shell → legge anche le variabili locali → modifiche persistono.
Commenti recenti