GNU/Linux >> Tutoriels Linux >  >> Linux

Les variables non environnementales transmises au sous-shell sont-elles invoquées par la substitution de commande ?

Le manuel de Bash dit :

La substitution de commandes, les commandes regroupées entre parenthèses et les commandes asynchrones sont appelées dans un environnement de sous-shell qui est un doublon de l'environnement du shell,
sauf que les interruptions interceptées par le shell sont réinitialisées aux valeurs que le shell a héritées de son parent à appel.

Dans cet exemple, b n'est pas une variable d'environnement, donc b n'existe pas dans le sous-shell créé par la substitution de commande. Alors pourquoi est c attribué la valeur de b par substitution de commande ? Est-ce parce que l'expansion des paramètres se produit pour $b dans le processus shell avant de créer un sous-shell pour exécuter echo 1 ?

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

Réponse acceptée :

Non, le sous-shell a été créé en premier.

Un environnement d'exécution de shell contient des paramètres de shell définis par des affectations de variables et des variables d'environnement. Un environnement de sous-shell a été créé en dupliquant l'environnement shell, il contient donc toutes les variables de l'environnement shell actuel.

Voir l'exemple :

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

La sortie est 2 au lieu de 1 .

Un environnement de sous-shell créé par substitution de commande est différent d'un environnement de shell créé en appelant l'exécutable du shell.

Lorsque vous appelez le shell en tant que :

$ bash -c :

le shell actuel a utilisé execve() pour créer un nouveau processus shell, quelque chose comme :

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

le dernier argument passé à execve contient toutes les variables d'environnement.

C'est pourquoi vous devez exporter les variables pour les pousser vers les variables d'environnement, qui seront incluses dans les commandes exécutées ultérieurement :

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

Notez que les variables d'environnement passent de 64 à 65. Et les variables qui ne sont pas exportées ne seront pas transmises au nouvel environnement shell :

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

Notez que les variables d'environnement sont toujours 65.

Dans la substitution de commande, le shell a utilisé fork() pour créer un nouveau processus shell, qui vient de copier l'environnement shell actuel - qui contient à la fois l'ensemble de variables et les variables d'environnement.


Linux
  1. Comment définir/créer des variables d'environnement et de shell sous Linux

  2. Comment affecter la sortie d'une commande à une variable Shell ?

  3. Existe-t-il des conventions de nommage pour les variables dans les scripts shell ?

  4. Utilisation des variables d'environnement dans la commande cURL - Unix

  5. Comment exécuter la commande Vim depuis le shell ?

Alias ​​de ligne de commande dans le shell Linux

La différence d'utilisation entre les variables shell et les variables d'environnement ?

Linux - Les variables d'environnement sont-elles visibles pour les utilisateurs non privilégiés sous Linux ?

Quels sont les différents types de shells sous Linux ?

useradd vs adduser :quelles sont les différences ?

Masquer la sortie d'une commande shell uniquement en cas de succès ?