GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum ist eine Variable in einer Subshell sichtbar?

Das Learning Bash Book erwähnt, dass eine Subshell nur Umgebungsvariablen und Dateideskriptoren usw. erben wird und dass sie keine Variablen erben wird, die nicht exportiert werden:

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

$

Wie ich weiß, erstellt die Shell zwei Subshells für () und für ./file , aber warum im () Fall identifiziert die Subshell die var Variable, obwohl sie nicht exportiert wird und in der ./file falls es es nicht identifiziert hat?

# 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

Ich habe versucht, strace zu verwenden um herauszufinden, wie das passiert, und überraschenderweise fand ich heraus, dass bash dieselben Argumente für den Klon-Systemaufruf verwendet, was bedeutet, dass sowohl der gegabelte Prozess in () und ./file sollte denselben Prozessadressraum wie der Elternprozess haben, also warum in () case ist die Variable, die für die Subshell sichtbar ist, und dasselbe gilt nicht für ./file Fall, obwohl dieselben Argumente auf dem Clone-Systemaufruf basieren?

Akzeptierte Antwort:

Das Learning Bash Book ist falsch. Subshells erben alle Variablen. Sogar $$ (die PID der ursprünglichen Shell) wird beibehalten. Der Grund dafür ist, dass sich die Shell bei einer Subshell nur verzweigt und keine neue Shell ausführt (im Gegenteil, wenn Sie ./file eingeben , wird ein neuer Befehl ausgeführt, z. eine neue Hülle; Sehen Sie sich in der Strace-Ausgabe execve an und ähnliches). Im Grunde ist es also nur eine Kopie (mit einigen dokumentierten Unterschieden).

Hinweis:Dies ist nicht spezifisch für Bash; das gilt für jede Shell.


Linux
  1. Warum zeigt /bin/sh auf /bin/dash und nicht auf /bin/bash?

  2. Warum funktioniert find -exec mv {} ./target/ + nicht?

  3. Kopieren und überschreiben Sie eine Datei im Shell-Skript

  4. Zeile mit Shell-Skript an die Datei /etc/hosts anhängen

  5. unix:///var/run/supervisor.sock keine solche Datei

Was ist Subshell in Linux?

/proc/cpuinfo- und /proc/meminfo-Dateien unter Linux

Die Dateien /proc/mounts, /etc/mtab und /proc/partitions verstehen

Was ist eine .sh-Datei?

Warum sind < oder > erforderlich, um /dev/tcp

Sollten Websites gemäß der empfohlenen Verwendung in /var/ oder /usr/ leben?