Чи є $ () передплатою?


51

Я розумію, що це синтаксис нижньої оболонки (<commands...>), - це $()лише піддійна оболонка, з якої можна отримати змінні значення?

Примітка. Це стосується базису 4.4 на основі різних формулювань у їхній документації.


Відповіді:


75

$(…)є нижньою оболонкою за визначенням: це копія стану виконання оболонки¹, і зміни стану, внесені в нижню оболонку, не впливають на батьківську. Задійна оболонка, як правило, реалізується шляхом розгортання нового процесу (але деякі оболонки можуть оптимізувати це в деяких випадках).

Це не підказка, з якої можна отримати змінні значення. Якби зміни змінних впливали на батьків, це не буде підзаголовок. Це допоміжна оболонка, вихід якої батько може отримати. Підскла, створений компанією, $(…)має стандартний вихід, встановлений на трубу, і батьківський зчитує з цієї труби і збирає вихід.

Існує кілька інших конструкцій, які створюють підшару. Я думаю, що це повний список для bash:

  • Subshell для групування : ( … )нічого не створює, крім як створити підзаголовок і чекати його закінчення). Порівнюйте, з { … }якими групами командує виключно для синтаксичних цілей і не створює підшару.
  • Передумови : … &створює підзарядку і не чекає, коли вона закінчиться.
  • Трубопровід : … | …створює дві підгрубки, одну для лівої та іншу для правої, і чекає, коли обоє завершаться. Оболонка створює трубу і підключає стандартний вихід лівого боку до кінця запису, а правий - стандартний вхід до кінця зчитування. У деяких оболонках (ksh88, ksh93, zsh, bash з набором lastpipeопцій та ефективною) правий бік працює в оригінальній оболонці, тому конструкція трубопроводу створює лише одну підзаглушку.
  • Підстановка команд : $(…)(також написано `…`) створює підзарядку зі своїм стандартним вихідним кодом, встановленим на трубу, збирає вихід у материнській програмі та розширюється до цього виводу за вирахуванням останніх рядків. (І результат може бути додатково предметом розщеплення та глобалізації, але це вже інша історія.)
  • Підстановка процесу : <(…)створює підзаглушку зі стандартним набором виводу на трубу і розширюється до назви труби. Батьківський (або який-небудь інший процес) може відкрити трубу для зв'язку з передплатою. >(…)робить те саме, але з трубою на стандартному вході.
  • Coprocess : coproc …створює підзарядку і не чекає, коли вона закінчиться. Стандартний вхід і вихід підкладинки - це кожен набір на трубу, батьківський підключений до іншого кінця кожної труби.

¹ На відміну від запуску окремої оболонки .


Чи можете ви також включити ${...}у відповідь?
користувач1717828

3
@ user1717828 Що? Чому? Що пов'язане з розширенням розширення дистанційно пов'язане з цим питанням? Я не збираюся включати цілий посібник з оболонкою у свою відповідь.
Жил "ТАК - перестань бути злим"

1
Що пов'язане з розширенням розширення дистанційно пов'язане з цим питанням? Я не знаю, тому я запитав :-) Тож я здогадуюсь, що заміна фігурних підтяжок є не що інше, як підміна дужки дужок.
користувач1717828

@ user1717828: розширення змінної не пов'язане з підшарпами; це взагалі окремий механізм, і, безумовно, варто ознайомитися, якщо ви тільки починаєте!
0xdd

1
@EnricoMariaDeAngelis Це не єдиний спосіб, але це найбільш природний спосіб. Інший спосіб - command | { read line; … }(залежно від оболонки, lineможе бути, а може і не доступний після трубопроводу). Усі способи включають в себе допоміжну оболонку, оскільки команда, яка виробляє вихід, повинна виконуватись незалежно від оболонки, яка зчитує вхід. Якщо команда є виключно внутрішньою для оболонки (тільки конструкції оболонки та вбудовані елементи, ніяких зовнішніх команд), оболонка може не створити підпроцес, але це лише оптимізація, вона все ще створює підзарядку.
Жил "ТАК - перестань бути злим"

20

З сторінки man bash (1) у версії 4.4 bash, розділу "Розширення", підрозділу "Заміна команд":

Bash виконує розширення, виконуючи commandв середовищі підзаголовка [...]



1
Цікаво, що під CentOS 7 на сторінці сторінки 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.мені цікаво, чи це був навмисний упущення.
dr01

6
@ dr01 Навпаки, bash 4.4 змінив формулювання цього речення, щоб включити слово "subhell". Це було уточненням: в посібнику було чітко зазначено, що різні інші конструкції були підрозділами, але до 4.4 він не був чітко вказаний для заміни команд.
Жил "ТАК - перестань бути злим"

Так, на CentOS v7.4.1708 (досить недавній) баш - v4.2.46.
dr01

5

Так, ( commands... )це bashдопоміжна частина, яка буде виконуватися commands...в іншому процесі.

Єдина відмінність у вас $( commands... )полягає в тому, що ця частина коду після виконання commands...буде замінена всім, до чого commands...написано stdout.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.