GNU/Linux >> Linux Esercitazione >  >> Linux

Se i processi ereditano l'ambiente del genitore, perché abbiamo bisogno dell'esportazione?

Ho letto qui che lo scopo di export in una shell è rendere la variabile disponibile ai sottoprocessi avviati dalla shell.

Tuttavia, ho anche letto qui e qui che "I processi ereditano il loro ambiente dal genitore (il processo che li ha avviati)."

Se questo è il caso, perché abbiamo bisogno di export ? Cosa mi sto perdendo?

Le variabili della shell non fanno parte dell'ambiente per impostazione predefinita? Qual è la differenza?

Risposta accettata:

La tua ipotesi è che le variabili della shell siano nell'ambiente . Questo non è corretto. L'export comando è ciò che definisce un nome nell'ambiente. Quindi:

a=1 b=2
export b

risulta nella shell corrente sapendo che $a si espande a 1 e $b a 2, ma i sottoprocessi non sapranno nulla di a perché non fa parte dell'ambiente (anche nella shell corrente).

Alcuni strumenti utili:

  • set :Utile per visualizzare i parametri della shell corrente, esportati o meno
  • set -k :imposta argomenti assegnati nell'ambiente. Considera f() { set -k; env; }; f a=1
  • set -a :dice alla shell di inserire qualsiasi nome che viene impostato nell'ambiente. Come mettere export prima di ogni incarico. Utile per .env file, come in set -a; . .env; set +a .
  • export :dice alla shell di inserire un nome nell'ambiente. Esportazione e assegnazione sono due operazioni completamente diverse.
  • env :Come comando esterno, env posso solo parlarti degli ereditati ambiente, quindi, è utile per il controllo di integrità.
  • env -i :Utile per ripulire l'ambiente prima di avviare un processo secondario.

Alternative a export :

  1. name=val command # L'assegnazione prima del comando esporta quel nome nel comando.
  2. declare/local -x name # Esporta il nome, particolarmente utile nelle funzioni di shell quando si desidera evitare di esporre il nome a scopi esterni.
  3. set -a # Esporta ogni compito successivo.

Motivazione

Allora perché le shell devono avere le proprie variabili e un ambiente diverso? Sono sicuro che ci sono alcune ragioni storiche, ma penso che la ragione principale sia lo scopo. L'ambiente è per i sottoprocessi, ma ci sono molte operazioni che puoi fare nella shell senza biforcare un sottoprocesso. Supponiamo di eseguire il loop:

for i in {0..50}; do
    somecommand
done

Perché sprecare memoria per somecommand includendo i , rendendo il suo ambiente più grande di quanto dovrebbe essere? E se il nome della variabile che hai scelto nella shell significasse qualcosa di non previsto per il programma? (I miei preferiti personali includono DEBUG e VERBOSE . Questi nomi sono usati ovunque e raramente spazi dei nomi in modo adeguato.)

Correlati:cosa significa questo output da xev?

Cos'è l'ambiente se non la shell?

A volte per capire il comportamento di Unix devi guardare le syscalls, l'API di base per interagire con il kernel e il sistema operativo. Qui, stiamo esaminando l'exec famiglia di chiamate, che è ciò che usa la shell quando crea un sottoprocesso. Ecco una citazione dalla manpage per exec(3) (sottolineatura mia):

Il execle() e execvpe() le funzioni consentono al chiamante di specificare l'ambiente del programma eseguito tramite l'argomento envp. L'argomento envp è una matrice di puntatori a stringhe con terminazione null e deve essere terminato da un puntatore NULL. Le altre funzioni prendono l'ambiente per la nuova immagine di processo dalla variabile esterna environ nel processo di chiamata.

Quindi scrivendo export somename nella shell sarebbe equivalente a copiare il nome nel dizionario globale environ in C. Ma assegnando somename senza esportarlo sarebbe come assegnarlo in C, senza copiarlo nell'environ variabile.


Linux
  1. Qual è il miglior modo indipendente dalla distribuzione/shell per impostare le variabili d'ambiente?

  2. Perché il ~/.bash_profile non funziona?

  3. Perché "sudo Su" in uno script di shell non esegue il resto dello script come root?

  4. Perché il Pgid dei processi figlio non è il Pid del genitore?

  5. Perché non riesco a esportare il display Linux?

Che cos'è la shell in Linux?

Perché Bashrc controlla se la shell corrente è interattiva?

È possibile modificare l'ambiente di un processo genitore in Python?

Perché il kernel è mappato allo stesso spazio di indirizzi dei processi?

Perché l'utente "bin" ha bisogno di una shell di login?

Qual è il modo migliore per impostare una variabile d'ambiente in .bashrc?