Il comando source

Quando si esegue uno script Bash ci sono due modalità principali da impiegare, che hanno conseguenze diverse sull’ambiente della shell.

1. Esecuzione diretta (./script.sh)

  • Lo script viene eseguito in un nuovo processo figlio della shell corrente.
  • È equivalente a lanciare: sh script.sh oppure bash 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.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.