Почему переменные, не относящиеся к среде, передаются в подоболочку, вызываемую подстановкой команд?

perl -F'/\h*,\h*/' -lpe '$_ = join $\, @F' yourcsvfile

Если вас беспокоят конечные пробелы, увеличьте еще на 1 шаг:

perl -F'/\h*,\h*/' -lpe '$_ = join $\, @F;s/\h+$//'  yourcsvfile
0
12.02.2016, 17:14
3 ответа

Нет, сначала была создана подоболочка.

Среда выполнения оболочки содержит параметры оболочки, заданные назначениями переменных и переменными среды. Среда под-оболочки была создана путем дублирования среды оболочки, поэтому она содержит все переменные текущей среды оболочки.

См. пример:

$ 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, так и переменные окружения.

6
28.01.2020, 02:13

Да, b не является переменной среды.
Но: Да, b существует в подоболочке, созданной с помощью подстановки команд:

$ b=11; c="$(echo $b)"; echo "$c"          ### b exists in subshell.
11
$ b=11; c="$(b=33; echo $b)"; echo "$c"    ### $b is not replaced before
33                                         ### the subshell is executed.

То, что не получает переменные, является «полным дочерним процессом» :

$ b=11; bash -c 'echo "<$b>"'              ### b does not exist.
<>
$ b=11 bash -c 'echo "<$b>"'               ### environment b.
<11> 

Кроме что процесс, конечно, может получать переменные в среде.


Последняя строка в Подоболочка Wooledge :

В подоболочке видна обычная переменная оболочки a; но поскольку он не экспортируется, полный дочерний процесс его не видит.

3
28.01.2020, 02:13

Подстановка команды вызывает нормальный вызов интерпретатора оболочки, и этот интерпретатор запускает команду echo в подпроцессе .

Подпроцесс необходим, поскольку оболочке необходимо установить канал для команды echo , чтобы иметь возможность читать результаты.

Подпроцесс , который запускает команду echo , создается fork () , и это создает копии всех переменных из основного процесса оболочки. Вот почему $ b доступен с помощью команды echo .

2
28.01.2020, 02:13

Теги

Похожие вопросы