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


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.