GNU/Linux >> Linux Esercitazione >  >> Linux

Qual è la differenza tra l'esecuzione di uno script Bash e l'approvvigionamento?

Approvvigionamento uno script eseguirà i comandi nel file current processo shell.

Esecuzione uno script eseguirà i comandi in un nuovo processo shell.

Utilizzare source se si desidera che lo script modifichi l'ambiente nella shell attualmente in esecuzione. usa esegui altrimenti.

l '"ambiente" sono cose come la directory di lavoro corrente e le variabili d'ambiente. anche le impostazioni della shell (tra le altre funzionalità di cronologia e completamento). ce ne sono altri ma quelli sono i più visibili.

Se desideri maggiori dettagli, continua a leggere.

Terminologia

Per chiarire un po' di confusione comune sulla sintassi da eseguire e la sintassi da generare:

./myscript

Questo verrà eseguito myscript a 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 essere) 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 di shell valido. Il file può trovarsi nella directory corrente o in una directory in $PATH .

. myscript

Anche questo fonte myscript . Questa "ortografia" è quella ufficiale definita da POSIX. Bash ha definito source come alias del punto.

e per completezza:

exec myscript

Ciò terminerà la shell corrente e quindi eseguirà myscript al posto della shell terminata. Ciò significa che quando myscript è finito non c'è nessuna vecchia shell a cui tornare. exec è potente ma raramente necessario.

Ho messo alcuni link alla fine per ulteriori informazioni su questi argomenti.

Dimostrazione

Considera 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 è definito e siamo nella home directory.

Ora 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 è impostato 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 successivo mostra che la variabile non è impostata e la directory non è stata modificata. Quello che è successo? Le modifiche sono state apportate in un nuovo guscio. L'corrente shell ha generato un nuovo 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 distrutte con la nuova shell. Solo il testo di output viene stampato nella shell corrente.

Ora fontiamo 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 è cambiata.

L'approvvigionamento dello script non crea una nuova shell. Tutti i comandi vengono eseguiti nella shell corrente e le modifiche all'ambiente hanno effetto nella shell corrente.

Si noti che in questo semplice esempio l'output dell'esecuzione è lo stesso del sourcing dello script. Questo non è necessariamente sempre il caso.

Un'altra dimostrazione

Considera di seguire lo script pid.sh :

#!/bin/sh
echo $$

(la variabile speciale $$ si espande nel PID dell'attuale processo shell in esecuzione)

Prima stampa il PID della shell corrente:

$ echo $$
25009

Fonte dello script:

$ source pid.sh
25009

Esegui lo script, prendi nota del PID:

$ ./pid.sh
25011

Fonte ancora:

$ source pid.sh
25009

Esegui di nuovo:

$ ./pid.sh
25013

Puoi 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 è il nuovo shell creata per l'esecuzione dello script. Il sourcing dello script non crea una nuova shell e quindi il PID rimane lo stesso.

Riepilogo

Sia l'approvvigionamento che l'esecuzione dello script eseguiranno i comandi nello script riga per riga, come se avessi digitato quei comandi a mano riga per riga.

Le differenze sono:

  • Quando esegui lo script che stai aprendo un nuovo shell, digitare i comandi nella nuova shell, copiare l'output nella shell corrente, quindi chiudere la nuova shell. Eventuali modifiche all'ambiente avranno effetto solo nella nuova shell e andranno perse una volta chiusa la nuova shell.
  • Quando fonti lo script stai digitando i comandi nel tuo current guscio. Eventuali modifiche all'ambiente avranno effetto e rimarranno nella shell corrente.

Utilizzare source se si desidera che lo script modifichi l'ambiente nella shell attualmente in esecuzione. usa esegui altrimenti.

Vedi anche:

  • https://stackoverflow.com/questions/6331075/why-do-you-need-dot-slash-before-script-name-to-run-it-in-bash
  • https://askubuntu.com/questions/182012/is-there-a-difference-between-and-source-in-bash-after-all
  • https://stackoverflow.com/questions/18351198/what-are-the-uses-of-the-exec-command-in-shell-scripts

L'esecuzione di uno script lo esegue in un processo figlio separato, ovvero viene richiamata un'istanza separata di shell per elaborare lo script. Ciò significa che qualsiasi variabile d'ambiente, ecc., definita nello script non può essere aggiornato nella shell madre (corrente).

Sourcing di uno script significa che viene analizzato ed eseguito dalla stessa shell corrente. È come se avessi digitato il contenuto dello script. Per questo motivo, non è necessario che lo script di origine sia 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 lo faccio:

$ set `date`
$ source ./a.sh

Ottengo qualcosa del tipo:

a Fri Dec 11 07:34:17 PST 2009

Considerando che:

$ set `date`
$ ./a.sh

mi dà:

a

Spero di esserti stato d'aiuto.


sourcing è essenzialmente lo stesso che digitare ogni riga dello script al prompt dei comandi una 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.


Linux
  1. La differenza tra l'approvvigionamento ("." O "sorgente") ed eseguire un file in Bash?

  2. La differenza tra gli operatori Bash [[ Vs [ Vs ( Vs ((?

  3. Qual è la differenza tra strtok_r e strtok_s in C?

  4. Qual è la differenza tra nohup e e commerciale

  5. Qual è la differenza tra &> e >&in bash?

Qual è la differenza tra InnoDB e MyISAM?

Qual è la differenza tra Linux e Unix?

Qual è la differenza tra Login e Non-Login Shell

Che cos'è un hypervisor? Qual è la differenza tra il tipo 1 e 2?

Qual è la differenza tra curl e Wget?

qual è la differenza tra rimontare e smontare/montare?