При запуске команды оболочки в сценариях оболочки генерируется процесс подчиненной оболочки. Разве процесс не генерируется fork function? Почему переменные, которые не экспортируются, не наследуются? В fork весь контекст родительского процесса должен быть скопирован в подпроцесс.

1 ответ1

0

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

В этот момент, после прочтения страницы руководства для execve() должен появиться свет. Одним из параметров системного вызова является среда, которую будет иметь перекрывающийся образ процесса при запуске программы. Очевидно, что нет никакой волшебной скрытой среды, проходящей мимо операционной системы. Оболочка должна явно создать среду и передать ее в execvce() в дочернем процессе. Эта среда может быть любой, что нравится оболочке.

Что подводит нас ко второй ошибке. Переменные среды не являются переменными оболочки. Когда запускается программа оболочки, она импортирует переменные среды в переменные оболочки с одинаковыми именами (и в одной оболочке в функции оболочки). Когда дело доходит до порождения внешней команды, она затем экспортирует переменные оболочки в (новую) среду, которую она создает, и передает ядру в execve() . Между тем все, что вы делаете в сценариях и в интерактивном режиме с переменными оболочки, влияет на те переменные, которые отличаются от среды процесса оболочки. (Среда процесса оболочки обычно остается практически нетронутой и неиспользуемой после импорта при запуске программы.)

Который - эй престо! - объясняет, почему встроенная оболочка export называется "экспорт".

И это также объясняет, как встроенные модули, такие как set видят непредставленные переменные. Они не подразумевают наложение программы оболочки на другую программу и не требуют настройки новой среды для передачи в execve() . Точно так же создание подоболочек с круглыми скобками само по себе не включает execve() и поэтому не требует экспорта переменных оболочки для создания среды.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .