Нет, сначала была создана подоболочка.
Среда выполнения оболочки содержит параметры оболочки, заданные назначениями переменных и переменными среды. Среда под-оболочки была создана путем дублирования среды оболочки, поэтому она содержит все переменные текущей среды оболочки.
См. пример:
$ b=1
$ c=$(b=2; echo "$b")
$ echo "$c"
2
Выводится 2
вместо 1
.
Подпрограммное окружение, созданное путем подстановки команд, отличается от окружения оболочки, созданного путем вызова исполняемого файла оболочки.
Когда вы вызываете shell как:
$ bash -c :
текущий shell использовал execve() для создания нового процесса shell, что-то вроде:
execve("/bin/bash", ["bash", "-c", ":"], [/* 64 vars */]) = 0
последний аргумент, переданный execve
, содержит все переменные окружения.
Поэтому вам нужно экспортировать переменные, чтобы переместить их в переменные окружения, которые будут включены в последующие выполняемые команды:
$ a=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++
Обратите внимание, что переменные окружения меняются с 64 на 65. А переменные, которые не экспортированы, не будут переданы в новое окружение оболочки:
$ a=; b=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++
Обратите внимание, что переменные окружения по-прежнему 65.
При подмене команд оболочка использовала fork() для создания нового процесса оболочки, который просто скопировал текущее окружение оболочки - которое содержит как переменные set, так и переменные окружения.