GNU/Linux >> Linux Esercitazione >  >> Linux

Le variabili non ambientali vengono trasferite alla subshell invocate dalla sostituzione del comando?

Il manuale di Bash dice:

La sostituzione dei comandi, i comandi raggruppati tra parentesi e i comandi asincroni vengono invocati in un ambiente di sottoshell che è un duplicato dell'ambiente di shell,
tranne per il fatto che le trap catturate dalla shell vengono reimpostate sui valori che la shell ha ereditato dal suo genitore in invocazione.

In questo esempio,b non è una variabile di ambiente, quindi b non esiste nella subshell creata dalla sostituzione del comando. Allora perché c assegnato il valore di b per sostituzione di comando? È perché l'espansione del parametro avviene per $b nel processo della shell prima di creare una subshell per eseguire echo 1 ?

$ b=1
$ c=$(echo $b)
$ echo $c
1

Risposta accettata:

No, è stata creata prima la subshell.

Un ambiente di esecuzione della shell contiene parametri della shell impostati da assegnazioni di variabili e variabili di ambiente. Un ambiente subshell è stato creato duplicando l'ambiente shell, quindi contiene tutte le variabili dell'ambiente shell corrente.

Vedi l'esempio:

$ b=1
$ c=$(b=2; echo "$b")
$ echo "$c"
2

L'output è 2 invece di 1 .

Un ambiente di sottoshell creato dalla sostituzione di comandi è diverso con un ambiente di shell creato chiamando l'eseguibile della shell.

Quando chiami la shell come:

$ bash -c :

la shell corrente ha usato execve() per creare un nuovo processo di shell, qualcosa come:

execve("/bin/bash", ["bash", "-c", ":"], [/* 64 vars */]) = 0

l'ultimo argomento passato a execve contiene tutte le variabili d'ambiente.

Ecco perché è necessario esportare le variabili per inviarle alle variabili di ambiente, che verranno incluse nei comandi eseguiti successivamente:

$ a=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++

Nota che le variabili di ambiente cambiano da 64 a 65. E le variabili che non vengono esportate non verranno passate al nuovo ambiente shell:

$ a=; b=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++

Si noti che le variabili di ambiente sono ancora 65.

In sostituzione del comando, la shell ha utilizzato fork() per creare un nuovo processo di shell, che ha appena copiato l'ambiente della shell corrente, che contiene sia il set di variabili che le variabili di ambiente.


Linux
  1. Alias ​​della riga di comando nella shell di Linux

  2. Come impostare/creare variabili di ambiente e shell in Linux

  3. Come assegnare l'output di un comando a una variabile di shell?

  4. Il punto del comando esterno `cd`?

  5. La differenza di utilizzo tra variabili Shell e variabili d'ambiente?

Linux:le variabili d'ambiente sono visibili agli utenti non privilegiati su Linux?

Quali sono i diversi tipi di shell in Linux?

useradd vs. adduser:quali sono le differenze?

Utilizzo delle variabili d'ambiente nel comando cURL - Unix

Come eseguire il comando Vim dalla shell?

Nascondere l'output di un comando shell solo in caso di successo?