Чи виконуються функції як підпроцеси в Bash?


28

У Посібнику з розширеного сценарію Bash , наприклад 27-4 , 7-й рядок знизу, я прочитав це:

Функція працює як підпроцес.

Я робив тест у Баша, і, схоже, вищезазначене твердження є неправильним.

Пошуки на цьому сайті, Bash Man та моя пошукова система не приносять жодного світла.

Ви маєте відповідь і хотіли б пояснити?


12
Як зазначалося, цей посібник вкрай вводить в оману. Я рекомендую замість цього посібник Wooledge Bash .
Wildcard

Відповіді:


36

Посібник з розширеного сценарію Bash не завжди є надійним, і його прикладні скрипти містять застарілі практики, такі як використання фактично застарілих задніх посилань для заміни команд, тобто, `command`а не $(command).

У цьому конкретному випадку це відверто неправильно.

Розділ про функції оболонки в (канонічному) посібнику Bash остаточно говорить про це

Функції оболонки виконуються в поточному контексті оболонки; не створюється новий процес для їх інтерпретації.


10
"Розширений посібник з написання сценаріїв, як правило, недостовірний" Дуже вірно.
John1024

1
Чи можете ви надати посилання на підтримку вашого першого речення?
Буде Вузден

5
@WillVousden як виглядатиме посилання тут? Купа прикладів технічних недоліків керівництва? Документ, де експерти в баш-спільноті раніше відзначали, що це ненадійно? Чи допоможе це, якщо член стакковерлу з золотим значком у баші просто погодився у коментарі? : p
kojiro

3
@WillVousden Я не думаю, що те, що ти хочеш, існує в самій надійній формі. У минулому Mendel Cooper оновлював і виправляв проблеми з посібником, але публічного відстежувача помилок чи списку помилок немає. (Мабуть, це є найбільш грізним твердженням, яке я можу зробити.) Тож, коли ми знайдемо ваду (сприйняту чи реальну), все, що ми можемо зробити, - це надіслати електронною поштою автору та сподіватися на найкраще.
kojiro

3
@WillVousden, ... якщо вам потрібна історія того, як довго було досягнуто консенсусу в каналі freenode #bash, що слід уникати АБС, див. Wooledge.org/~greybot/meta/abs - друге поле у ​​кожному рядку - мітка часу, а перше - ім’я користувача; Я сподіваюся, що твердження про те, що ці імена користувачів є дуже шанованими особами, є достатнім.
Чарльз Даффі

32

Функції фігурних брекетів будуть виконуватись в процесі оболонки виклику, якщо їм не потрібна власна підпапка, яка є:

  • коли ви запускаєте їх у фоновому режимі з &
  • коли ви запускаєте їх як посилання в конвеєрі

Перенаправлення або додаткове оточення змінні не змушуватимуть нову підзарядку:

hw(){
    echo hello world from $BASHPID
    echo var=$var
} 
var=42 hw >&2
echo $BASHPID  #unexports var=42 and restores stdout here

Якщо ви визначите функцію з дужками замість фігур:

hw()(
  echo hello world from $BASHPID
)
hw 
echo $BASHPID

вона завжди буде працювати в новому процесі.

Заміна команд $()також завжди створює процеси в bash (але не в ksh, якщо ви запускаєте вбудовані всередині нього).


Я не знав, що f() (...)це дозволено. Чи є інші та інші визначення, крім {...}і (...)? У Баша я ще не в інших.
Томаш

1
@tomas Ви можете використовувати function hw { echo hello world; } синтаксис (не потрібно, ()якщо ви введете текст functionі зможете вказати переадресації відразу після фіналу }чи )як hw(){ echo error; } >&2. Це так.
PSkocik

2
Це відповідь, яку я одразу подумав, і вона абсолютно правильна. Його слід проголосувати як правильну відповідь. f()(...)завжди виконайте власну оболонку, а f(){...}ні.
rexkogitans

11
NB функції bash приймають будь-яку складну команду, тому foo() [[ x = x ]]є і правильним визначенням функції. Однак, якщо ви подивитеся на функцію, type fooви побачите, що це все ще синтаксичний цукор для foo() { [[ x = x ]]; }. Те саме стосується функцій підзарядки: bar() ( : )стає bar() { ( : ); }.
kojiro

1
@kojiro приємно +1. не знав цього
PSkocik

9

Команда, про яку йдеться у цьому прикладі, виглядає так:

echo ${arrayZ[@]/%e/$(replacement)}

Приклад пізніше говорить:

#    $( ... ) is command substitution.
#    A function runs as a sub-process.

Будучи добродійним до керівництва по ABS, те, що вони, мабуть, мали на меті написати, це те, що функція працює всередині підстановки команд, а команда всередині підстановки команди працює в нижній частині .


Це дуже оманливо. Дякуємо за вашу інтерпретацію
Томаш

5
@tomas "дуже оманливий". Так, дуже. На відміну від посібника з ABS, Wiki Greg є прекрасним джерелом розширеної інформації про башти.
John1024

1
Ура. Яка ваша думка щодо цього: wiki.bash-hackers.org/start ?
Томаш

@tomas Я не знаю про це з перших рук.
John1024

2
@tomas, ... моя власна думка щодо вікі-хакерів - це відмінне джерело. Я не переглядав це так всебічно, як у мене є вікі Wooledge, але це, як правило, точно і точно написано.
Чарльз Даффі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.