Risposta breve
Nella tua domanda, il secondo comando non usa né l' .
integrato della shell né quello source
incorporato. Invece, stai effettivamente eseguendo lo script in una shell separata, invocandolo per nome come faresti con qualsiasi altro file eseguibile. Questo gli dà un insieme separato di variabili (anche se se esporti una variabile nella sua shell genitore, sarà una variabile d'ambiente per qualsiasi processo figlio , e quindi sarà inclusa nelle variabili di una shell figlio ). Se cambi il /
in uno spazio, questo lo eseguirà con il .
built-in, che è equivalente a source
.
Spiegazione estesa
Questa è la sintassi della source
shell integrata, che esegue il contenuto di uno script nella shell corrente (e quindi con le variabili della shell corrente):
source testenv.sh
Questa è la sintassi del .
built-in, che fa la stessa cosa di source
:
. testenv.sh
Tuttavia, questa sintassi esegue lo script come file eseguibile, avviando una nuova shell per eseguirlo:
./testenv.sh
Quello non sta usando il .
built-in. Piuttosto, .
fa parte del percorso del file che si sta eseguendo. In generale, è possibile eseguire qualsiasi file eseguibile in una shell invocandolo con un nome che contiene almeno un /
carattere. Per eseguire un file nella directory corrente, precederlo ./
è quindi il modo più semplice. A meno che la directory corrente non sia nella tua PATH
, non puoi eseguire lo script con il comando testenv.sh
. Questo per impedire alle persone di eseguire accidentalmente file nella directory corrente quando intendono eseguire un comando di sistema o qualche altro file esistente in alcune directory elencate nella PATH
variabile d'ambiente.
Poiché l'esecuzione di un file per nome (anziché con source
o .
) lo esegue in una nuova shell, avrà un proprio set di variabili shell. La nuova shell eredita le variabili di ambiente dal processo chiamante (che in questo caso è la shell interattiva) e tali variabili di ambiente diventano variabili di shell nella nuova shell. Tuttavia, affinché una variabile di shell sia passata alla nuova shell, è necessario che si verifichi una delle seguenti condizioni:
La variabile shell è stata esportata, facendola diventare una variabile d'ambiente. Utilizzare la export
shell integrata per questo. Nel tuo esempio, puoi usare export MY_VAR=12345
per impostare ed esportare la variabile in un solo passaggio, o se è già impostata puoi semplicemente usare export MY_VAR
.
La variabile shell viene esplicitamente impostata e passata per il comando in esecuzione, causando che sia una variabile di ambiente per la durata del comando in esecuzione. Questo di solito realizza che:
MY_VAR=12345 ./testenv.sh
Se MY_VAR
è una variabile di shell che non è stata esportata, puoi anche eseguirla testenv.sh
con MY_VAR
passata come variabile di ambiente impostandola su se stessa :
MY_VAR="$MY_VAR" ./testenv.sh
./
La sintassi per gli script richiede una linea di Hashbang per funzionare (correttamente)
A proposito, si ricorda che, quando invoke un eseguibile per nome come sopra (e non con il .
o source
shell built-in), che cosa shell programma viene utilizzato per eseguirlo è non generalmente determinato da ciò che si sta eseguendo shell da . Anziché:
Per i file binari, il kernel può essere configurato per eseguire file di quel particolare tipo. Esamina i primi due byte del file per un "numero magico" che indica che tipo di eseguibile binario è. Ecco come possono essere eseguiti i file binari eseguibili.
Questo è, ovviamente, estremamente importante, perché uno script non può essere eseguito senza una shell o un altro interprete, che è un file binario eseguibile! Inoltre, molti comandi e applicazioni sono binari compilati anziché script.
( #!
è la rappresentazione testuale del "numero magico" che indica un eseguibile testuale.)
Per i file che dovrebbero essere eseguiti in una shell o in un altro linguaggio interpretato, la prima riga appare come:
#!/bin/sh
/bin/sh
può essere sostituito con qualunque altra shell o interprete inteso per eseguire il programma. Ad esempio, un programma Python potrebbe iniziare con la riga:
#!/usr/bin/python
Queste linee sono chiamate hashbang, shebang e numerosi altri nomi simili. Vedi questa voce FOLDOC , questo articolo di Wikipedia e # # / / bin / sh è letto dall'interprete? per maggiori informazioni.
Se un file di testo è contrassegnato come eseguibile e lo si esegue dalla shell (come ./filename
) ma non inizia con #!
, il kernel non riesce a eseguirlo. Tuttavia, visto che questo è successo, la tua shell proverà ad eseguirla passando il suo nome ad una shell. Esistono pochi requisiti su quale shell sia ( "la shell eseguirà un comando equivalente a far invocare una shell ..." ). In pratica , alcune shell - incluso bash
* - eseguono un'altra istanza di se stesse, mentre altre usano/bin/sh
. Consiglio vivamente di evitarlo e utilizzare invece una riga hashbang (o eseguire lo script passandolo all'interprete desiderato, ad esempio bash filename
).
* Manuale GNU Bash , 3.7.2 Ricerca comandi ed esecuzione : "Se questa esecuzione fallisce perché il file non è in formato eseguibile e il file non è una directory, si presume che sia uno script di shell e la shell lo esegue come descritto negli script Shell . "
source
è che le funzioni sono diventate disponibili da Bash senza bisogno di caricare o riavviare. Esempio#!/bin/bash function olakease {echo olakease;}
. Una volta caricato,source file.sh
puoi chiamare direttamenteolakease
da bash. Mi piace molto La sorgente esegue quindi molte cose, il punto.
è solo per l'esecuzione ed è qualcosa di simile all'usobash file.sh