Я розумію, що це синтаксис нижньої оболонки (<commands...>)
, - це $()
лише піддійна оболонка, з якої можна отримати змінні значення?
Примітка. Це стосується базису 4.4 на основі різних формулювань у їхній документації.
Я розумію, що це синтаксис нижньої оболонки (<commands...>)
, - це $()
лише піддійна оболонка, з якої можна отримати змінні значення?
Примітка. Це стосується базису 4.4 на основі різних формулювань у їхній документації.
Відповіді:
$(…)
є нижньою оболонкою за визначенням: це копія стану виконання оболонки¹, і зміни стану, внесені в нижню оболонку, не впливають на батьківську. Задійна оболонка, як правило, реалізується шляхом розгортання нового процесу (але деякі оболонки можуть оптимізувати це в деяких випадках).
Це не підказка, з якої можна отримати змінні значення. Якби зміни змінних впливали на батьків, це не буде підзаголовок. Це допоміжна оболонка, вихід якої батько може отримати. Підскла, створений компанією, $(…)
має стандартний вихід, встановлений на трубу, і батьківський зчитує з цієї труби і збирає вихід.
Існує кілька інших конструкцій, які створюють підшару. Я думаю, що це повний список для bash:
( … )
нічого не створює, крім як створити підзаголовок і чекати його закінчення). Порівнюйте, з { … }
якими групами командує виключно для синтаксичних цілей і не створює підшару.… &
створює підзарядку і не чекає, коли вона закінчиться.… | …
створює дві підгрубки, одну для лівої та іншу для правої, і чекає, коли обоє завершаться. Оболонка створює трубу і підключає стандартний вихід лівого боку до кінця запису, а правий - стандартний вхід до кінця зчитування. У деяких оболонках (ksh88, ksh93, zsh, bash з набором lastpipe
опцій та ефективною) правий бік працює в оригінальній оболонці, тому конструкція трубопроводу створює лише одну підзаглушку.$(…)
(також написано `…`
) створює підзарядку зі своїм стандартним вихідним кодом, встановленим на трубу, збирає вихід у материнській програмі та розширюється до цього виводу за вирахуванням останніх рядків. (І результат може бути додатково предметом розщеплення та глобалізації, але це вже інша історія.)<(…)
створює підзаглушку зі стандартним набором виводу на трубу і розширюється до назви труби. Батьківський (або який-небудь інший процес) може відкрити трубу для зв'язку з передплатою. >(…)
робить те саме, але з трубою на стандартному вході.coproc …
створює підзарядку і не чекає, коли вона закінчиться. Стандартний вхід і вихід підкладинки - це кожен набір на трубу, батьківський підключений до іншого кінця кожної труби.${...}
у відповідь?
command | { read line; … }
(залежно від оболонки, line
може бути, а може і не доступний після трубопроводу). Усі способи включають в себе допоміжну оболонку, оскільки команда, яка виробляє вихід, повинна виконуватись незалежно від оболонки, яка зчитує вхід. Якщо команда є виключно внутрішньою для оболонки (тільки конструкції оболонки та вбудовані елементи, ніяких зовнішніх команд), оболонка може не створити підпроцес, але це лише оптимізація, вона все ще створює підзарядку.
З сторінки man bash (1) у версії 4.4 bash, розділу "Розширення", підрозділу "Заміна команд":
Bash виконує розширення, виконуючи
command
в середовищі підзаголовка [...]
bash
не згадується жодна підказка: Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.
мені цікаво, чи це був навмисний упущення.