GNU/Linux >> Tutoriels Linux >  >> Linux

Pourquoi une variable est-elle visible dans un sous-shell ?

Le Learning Bash Book mentionne qu'un sous-shell n'héritera que des variables d'environnement et des descripteurs de fichiers, etc., et qu'il n'héritera pas des variables qui ne sont pas exportées :

$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var

$

Comme je le sais, le shell créera deux sous-shells pour () et pour ./file , mais pourquoi dans le () cas le sous-shell identifie-t-il le var variable bien qu'elle ne soit pas exportée et dans le ./file au cas où il ne l'aurait pas identifié ?

# Strace for () 
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25617
# Strace for ./file
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25631

J'ai essayé d'utiliser strace pour comprendre comment cela se produit et, étonnamment, j'ai découvert que bash utiliserait les mêmes arguments pour l'appel système clone, ce qui signifie que le processus fourchu dans () et ./file devrait avoir le même espace d'adressage de processus que le parent, alors pourquoi dans le () case est la variable visible par le sous-shell et il n'en va pas de même pour le ./file cas, bien que les mêmes arguments soient basés sur l'appel système clone ?

Réponse acceptée :

Le Learning Bash Book est faux. Les sous-interpréteurs héritent de toutes les variables. Même $$ (le PID du shell d'origine) est conservé. La raison en est que pour un sous-shell, le shell se contente de bifurquer et n'exécute pas un nouveau shell (au contraire, lorsque vous tapez ./file , une nouvelle commande est exécutée, par ex. une nouvelle coquille; dans la sortie strace, regardez execve et similaires). Donc, fondamentalement, ce n'est qu'une copie (avec quelques différences documentées).

Remarque :ceci n'est pas spécifique à bash; ceci est vrai pour n'importe quel shell.


Linux
  1. Pourquoi l'utilisateur mysql a bash shell dans /etc/passwd ?

  2. Comment Linux gère-t-il plusieurs séparateurs de chemins consécutifs (/home////nom d'utilisateur///fichier) ?

  3. Ajouter une ligne au fichier /etc/hosts avec le script shell

  4. echo ou print /dev/stdin /dev/stdout /dev/stderr

  5. Pourquoi < ou > sont-ils nécessaires pour utiliser /dev/tcp

Qu'est-ce que le sous-shell sous Linux ?

Fichiers /proc/cpuinfo et /proc/meminfo sous Linux

Comprendre les fichiers /proc/mounts, /etc/mtab et /proc/partitions

Qu'est-ce qu'un fichier .sh ?

Pourquoi mettre des choses autres que /home sur une partition séparée ?

Les sites Web doivent-ils vivre dans /var/ ou /usr/ selon l'utilisation recommandée ?