Я понимаю, что синтаксис подоболочки (<commands...>)- это $()всего лишь подоболочка, из которой можно извлечь значения переменных?
Примечание: это относится к bash 4.4 на основании различных формулировок в их документации.
Я понимаю, что синтаксис подоболочки (<commands...>)- это $()всего лишь подоболочка, из которой можно извлечь значения переменных?
Примечание: это относится к bash 4.4 на основании различных формулировок в их документации.
Ответы:
$(…)по определению является подоболочкой: это копия состояния времени выполнения оболочки¹, и изменения состояния, внесенные в подоболочку, не влияют на родительский объект. Подоболочка обычно реализуется путем разветвления нового процесса (но некоторые оболочки могут оптимизировать это в некоторых случаях).
Это не подоболочка, из которой вы можете получить значения переменных. Если бы изменения в переменных оказали влияние на родителя, это не было бы подоболочкой. Это подоболочка, чей вывод может извлечь родитель. Для подоболочки, созданной с помощью $(…)стандартного вывода, задан канал, а родительский объект читает из этого канала и собирает выходные данные.
Есть несколько других конструкций, которые создают подоболочку. Я думаю, что это полный список для Bash:
( … )ничего не делает, кроме как создает подоболочку и ожидает ее завершения). Сравните с тем, { … }какие группы команд чисто для синтаксических целей и не создает подоболочки.… &создает подоболочку и не ожидает его завершения.… | …создает две подоболочки, одну для левой стороны и одну для правой стороны, и ожидает завершения обоих. Оболочка создает канал и соединяет стандартный вывод левой стороны с концом записи канала, а стандартный ввод правой стороны - с концом чтения. В некоторых оболочках (ksh88, ksh93, zsh, bash с установленной и действующей lastpipeопцией ) правая часть выполняется в исходной оболочке, поэтому конструкция конвейера создает только одну подоболочку.$(…)(также пишется `…`) создает подоболочку со стандартным выводом, установленным для канала, собирает выходные данные в родительском и расширяется до этого вывода, минуя завершающие символы новой строки. (И результат может быть далее подвергнут расщеплению и смещению, но это другая история.)<(…)создает подоболочку со стандартным выводом, установленным в канал, и расширяется до имени канала. Родитель (или какой-то другой процесс) может открыть канал для связи с подоболочкой. >(…)делает то же самое, но с трубкой на стандартном вводе.coproc …создает подоболочку и не ждет его завершения. Каждый стандартный вход и выход подоболочки настроен на канал, родительский элемент которого подключен к другому концу каждого канала.${...}в ответ?
command | { read line; … }(в зависимости от оболочки, lineможет или не может быть доступен после конвейера). Все способы включают в себя подоболочку, потому что команда, которая производит вывод, должна выполняться независимо от оболочки, которая читает ввод. Если команда является чисто внутренней по отношению к оболочке (только конструкции оболочки и встроенные функции, а не внешние команды), оболочка может не создавать подпроцесс, но это всего лишь оптимизация, она по-прежнему создает подоболочку.
Из справочной страницы bash (1) в bash версии 4.4, раздел «РАСШИРЕНИЕ», подраздел «Подстановка команд»:
Bash выполняет расширение, выполняя
commandв среде подоболочки [...]
bashman-странице не упоминается какая-либо подоболочка: Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.интересно, было ли это намеренным упущением.