Почему некоторые команды bash с каналом не работают

Я пытаюсь реализовать свою собственную оболочку, основанную на поведении bash, и я заметил, что некоторые команды не работают с каналами, например, если у меня есть: export AAA=test | cat, например, эта команда не будет добавлять AAA к переменным среды, поэтому экспорт не работает,

но если я напишу: export | cat, он напечатает переменную среды, так что здесь это похоже на работу экспорта, то же самое с выходом, неустановленным .... так может ли кто-нибудь объяснить мне это поведение и как я могу его реализовать?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
0
0
536
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

export в обоих случаях выполняется в подоболочке, среда которой является копией родительской оболочки.

С помощью export | cat вы копируете содержимое среды подоболочки, которое не было изменено из копии, полученной от родителя, поэтому вы получаете вывод, который соответствует тому, что мог бы получить только export.

С помощью export AAA=test | cat вы изменяете среду подоболочки, а не вызывающую оболочку. Кроме того, export в этом случае не записывает никаких выходных данных для чтения cat. После завершения конвейера подоболочка уничтожается, и управление возвращается к текущей оболочке, среда которой не была изменена.

Незначительная загвоздка: export AAA=test | cat на самом деле не изменяет среду подоболочки. Если эта подоболочка породила другую подоболочку, среда этой подоболочки будет иметь AAA в своей среде, но подоболочка, выполняющая команду export, не имеет измененной среды.

William Pursell 18.12.2020 19:32

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

REVERSI 18.12.2020 19:34

@REVERSI, в канале или нет, export не изменяет среду оболочки. Это влияет только на среду последовательно выполняемых команд.

William Pursell 18.12.2020 19:36

@WilliamPursell Я думаю, это зависит от того, что вы подразумеваете под «окружающей средой». export AAA=test обязательно устанавливает значение переменной с именем AAA в test в подоболочке. На самом деле нет никакой разницы (AFAIK) между переменными, инициализированными из родительской среды, и переменными, установленными позже. Это правда, что экспорт имени просто означает его пометку для использования при создании дочерней среды, а не запихивание переменной в какое-то отдельное пространство имен.

chepner 18.12.2020 19:38

да, я знаю, это не изменит переменные среды родительской оболочки (bash), но изменит переменную среды моей оболочки. но мне просто нужно знать, почему он добавляет к переменной окружения подоболочки в случае без канала, и если есть канал, он не будет добавляться к переменной окружения подоболочки

REVERSI 18.12.2020 19:40

@chepner Это верное замечание. Я думаю, что существует масса путаницы в отношении переменных и переменных среды, и, вероятно, лучше придерживаться точного определения «среды».

William Pursell 18.12.2020 19:40

Я предполагаю, что в операционных системах есть существенное различие, которое ограничивает объем памяти, доступной для объединенной среды, и аргументы для новой команды.

chepner 18.12.2020 19:40

@REVERSI Большинство оболочек реализуют конвейеры, разветвляя новые процессы для каждой команды. Некоторые оболочки (включая bash, если установлена ​​опция lastpipe) будут выполнять последнюю команду в текущей оболочке. Я не знаю ни одной оболочки, которая будет выполнять любую другую команду в текущей оболочке, хотя я не верю, что POSIX на самом деле запрещает это.

chepner 18.12.2020 19:45

@chepner Большое спасибо, это то, что я искал

REVERSI 18.12.2020 19:50

Другие вопросы по теме