Risposte:
Il sourcing di uno script eseguirà i comandi nel processo di shell corrente .
L'esecuzione di uno script eseguirà i comandi in un nuovo processo di shell.
Utilizzare source se si desidera che lo script cambi l'ambiente nella shell attualmente in esecuzione. usa esegui altrimenti.
Se sei ancora confuso, continua a leggere.
Per chiarire un po 'di confusione comune sulla sintassi da eseguire e la sintassi sull'origine:
./myscript
Ciò verrà eseguito a myscript
condizione che il file sia eseguibile e si trovi nella directory corrente. Il punto iniziale e la barra ( ./
) indica la directory corrente. Questo è necessario perché la directory corrente di solito non è (e di solito non dovrebbe esserlo) in $PATH
.
myscript
Questo verrà eseguito myscript
se il file è eseguibile e si trova in una directory in $PATH
.
source myscript
Questo fonte myscript
. Il file non deve essere eseguibile ma deve essere uno script shell valido. Il file può trovarsi nella directory corrente o in una directory in $PATH
.
. myscript
Anche questo fonte myscript
. Questa "ortografia" è quella ufficiale come definita da POSIX . Bash definito source
come alias al punto.
Considerare myscript.sh
con il seguente contenuto:
#!/bin/sh
# demonstrate setting a variable
echo "foo: "$(env | grep FOO)
export FOO=foo
echo "foo: "$(env | grep FOO)
# demonstrate changing of working directory
echo "PWD: "$PWD
cd somedir
echo "PWD: "$PWD
Prima di eseguire lo script, controlliamo l'ambiente corrente:
$ env | grep FOO
$ echo $PWD
/home/lesmana
La variabile FOO
non è definita e ci troviamo nella home directory.
Ora noi eseguiamo il file:
$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
Controlla di nuovo l'ambiente:
$ env | grep FOO
$ echo $PWD
/home/lesmana
La variabile FOO
non è impostata e la directory di lavoro non è cambiata.
L'output dello script mostra chiaramente che la variabile è stata impostata e la directory è stata modificata. Il controllo in seguito mostra che la variabile non è impostata e la directory non è stata modificata. Quello che è successo? Le modifiche sono state apportate in una nuova shell. La shell corrente ha generato una nuova shell per eseguire lo script. Lo script è in esecuzione nella nuova shell e tutte le modifiche all'ambiente hanno effetto nella nuova shell. Al termine dello script, la nuova shell viene distrutta. Tutte le modifiche all'ambiente nella nuova shell vengono eliminate con la nuova shell. Nella shell corrente viene stampato solo il testo di output.
Ora fonte il file:
$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
Controlla di nuovo l'ambiente:
$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir
La variabile FOO è impostata e la directory di lavoro è stata modificata.
Il sourcing dello script non crea una nuova shell. Tutti i comandi vengono eseguiti nella shell corrente e le modifiche all'ambiente diventano effettive nella shell corrente.
Si noti che in questo semplice esempio l'output dell'esecuzione è uguale all'approvvigionamento dello script. Questo non è sempre necessariamente il caso.
Prendi in considerazione il seguente script pid.sh
:
#!/bin/sh
echo $$
(la variabile speciale si $$
espande al PID dell'attuale processo di shell in esecuzione)
Prima stampa il PID della shell corrente:
$ echo $$
25009
Fonte lo script:
$ source pid.sh
25009
Eseguire lo script, notare il PID:
$ ./pid.sh
25011
Fonte di nuovo:
$ source pid.sh
25009
Eseguire di nuovo:
$ ./pid.sh
25013
Si può vedere che l'approvvigionamento dello script viene eseguito nello stesso processo mentre l'esecuzione dello script crea un nuovo processo ogni volta. Quel nuovo processo è la nuova shell creata per l'esecuzione dello script. Il sourcing dello script non crea una nuova shell e quindi il PID rimane lo stesso.
Sia l'approvvigionamento che l'esecuzione dello script eseguiranno i comandi nello script riga per riga, come se si digitassero tali comandi manualmente riga per riga.
Le differenze sono:
Utilizzare source se si desidera che lo script cambi l'ambiente nella shell attualmente in esecuzione. usa esegui altrimenti.
Guarda anche:
source myscript.sh
e . myscript.sh
?
L'esecuzione di uno script lo esegue in un processo figlio separato, ovvero viene invocata un'istanza separata della shell per elaborare lo script. Ciò significa che eventuali variabili di ambiente ecc., Definite nello script, non possono essere aggiornate nella shell genitore (corrente).
Il sourcing di uno script significa che viene analizzato ed eseguito dalla shell corrente stessa. È come se tu scrivessi il contenuto dello script. Per questo motivo, lo script di provenienza non deve essere eseguibile. Ma deve essere eseguibile se lo stai eseguendo, ovviamente.
Se hai argomenti posizionali nella shell corrente, sono invariati.
Quindi se ho un file a.sh
contenente:
echo a $*
e io faccio:
$ set `date`
$ source ./a.sh
Ottengo qualcosa del tipo:
a Fri Dec 11 07:34:17 PST 2009
Mentre:
$ set `date`
$ ./a.sh
mi da:
a
Spero che aiuti.
sourcing è essenzialmente lo stesso che digitare ogni riga dello script al prompt dei comandi uno alla volta ...
L'esecuzione avvia un nuovo processo e quindi esegue ogni riga dello script, modificando solo l'ambiente corrente in base a ciò che restituisce.
Oltre a quanto sopra, l'esecuzione dello script ./myscript
richiede l'autorizzazione di esecuzione per myscript dei file mentre l'approvvigionamento non richiede alcuna autorizzazione di esecuzione. Ecco perché chmod +x myscript
non è richiesto primasource myscript
bash myscript
.
Sourcing ottieni tutte le variabili extra definite nello script.
Pertanto, se si dispone di configurazioni di configurazione o di funzioni, è necessario eseguire il sorgente e non eseguire. Le esecuzioni sono indipendenti dall'ambiente dei genitori.
Se ricordo bene, l'esecuzione dello script esegue l'eseguibile in #!
linea con il file di script come argomento (in genere avvia una nuova shell e procede efficacemente allo script nella nuova shell, come con #!/bin/sh
);
mentre, l'approvvigionamento dello script esegue ogni riga nell'ambiente di shell corrente, il che è utile per mutare la shell corrente (ad esempio, fornendo un modo per definire le funzioni di shell ed esportare le variabili di ambiente).
source
Il comando esegue lo script fornito (l'autorizzazione eseguibile non è obbligatoria ) nell'ambiente shell corrente , mentre ./
esegue lo script eseguibile fornito in una nuova shell.
Inoltre, controlla questa risposta per esempio: https://superuser.com/a/894748/432100