Czy funkcje działają jako podprocesy w Bash?


28

W Advanced Bash-Scripting Guide , w przykładzie 27-4 , 7-ta linia od dołu przeczytałem:

Funkcja działa jako podproces.

Zrobiłem test w Bash i wydaje się, że powyższe stwierdzenie jest błędne.

Wyszukiwania w tej witrynie, Bash Man i moja wyszukiwarka nie przynoszą żadnego światła.

Czy znasz odpowiedź i chciałbyś wyjaśnić?


12
Jak wspomniano, przewodnik ten jest wyjątkowo mylący. Zamiast tego polecam Wooledge Bash Guide .
Wildcard

Odpowiedzi:


36

Advanced Bash-Scripting Guide nie zawsze jest niezawodny, a jego przykładowe skrypty zawierają przestarzałe praktyki, takie jak używanie efektywnie przestarzałych odwrotności do podstawiania poleceń, tj. `command`Zamiast $(command).

W tym konkretnym przypadku jest to rażąco niepoprawne.

Rozdział o funkcjach powłoki w (kanonicznym) podręczniku Bash definitywnie stwierdza, że

Funkcje powłoki są wykonywane w bieżącym kontekście powłoki; nie jest tworzony nowy proces ich interpretacji.


10
„Advanced Bash-Scripting Guide jest ogólnie zawodny” Bardzo prawda.
John1024,

1
Czy możesz podać odniesienia do pierwszego zdania?
Will Vousden

5
@WillVousden, jak wyglądałoby tutaj odniesienie? Kilka przykładów technicznych wad przewodnika? Dokument, w którym eksperci społeczności bash zauważyli wcześniej, że jest niewiarygodny? Czy pomogłoby to, gdyby członek stackoverflow ze złotą odznaką bash zgodził się w komentarzu? : p
kojiro

3
@WillVousden Nie sądzę, że to, czego chcesz, istnieje w wiarygodnej formie. Mendel Cooper w przeszłości aktualizował i naprawiał problemy z przewodnikiem, ale nie ma publicznego narzędzia do śledzenia błędów ani listy błędów. (Być może jest to najbardziej potępiające stwierdzenie, jakie mogę wypowiedzieć.) Więc kiedy znajdziemy wadę (postrzeganą lub prawdziwą), wszystko, co możemy zrobić, to wysłać wiadomość e-mail do autora i mieć nadzieję na najlepsze.
kojiro

3
@WillVousden ... jeśli chcesz historię o tym, jak długo konsensus w kanale freenode #bash było, że ABS należy unikać, zobacz wooledge.org/~greybot/meta/abs - drugie pole w każdej linii jest znacznikiem czasu, a pierwszy to nazwa użytkownika; Mam nadzieję, że wystarczające będzie stwierdzenie, że nazwy użytkowników są bardzo szanowanymi osobami.
Charles Duffy,

32

Funkcje nawiasów klamrowych będą działać w procesie powłoki wywołującej, chyba że potrzebują własnej podpowłoki, która jest:

  • gdy uruchomisz je w tle za pomocą &
  • po uruchomieniu ich jako łącza w potoku

Przekierowania lub dodatkowe środowisko zmienne nie wymuszą nowej podpowłoki:

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

Jeśli funkcja zostanie zdefiniowana za pomocą nawiasów zamiast curlies:

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

zawsze będzie działał w nowym procesie.

Podstawianie poleceń $()zawsze tworzy procesy w bash (ale nie w ksh, jeśli uruchamiasz wewnątrz niego wbudowane funkcje).


Nie wiedziałem, że f() (...)jest dozwolone. Czy są jakieś inne definicje oprócz {...}i (...)? W Bash nie interesuję się jeszcze innymi.
Tomasz

1
@tomas Możesz użyć function hw { echo hello world; } składni (nie musisz tego ()wpisywać functioni możesz określić przekierowania zaraz po finale }lub )jak w hw(){ echo error; } >&2. To wszystko
PSkocik

2
To odpowiedź, o której od razu pomyślałem i jest absolutnie poprawna. Należy głosować jako prawidłową odpowiedź. f()(...)zawsze wykonuje własną powłokę, podczas gdy f(){...}nie.
rexkogitans

11
Funkcje NB bash akceptują dowolne polecenia złożone, więc foo() [[ x = x ]]jest to również poprawna definicja funkcji. Jeśli jednak spojrzysz na funkcję za pomocą type foo, zobaczysz, że jest to nadal cukier syntaktyczny foo() { [[ x = x ]]; }. To samo dotyczy funkcji podpowłoki: bar() ( : )staje się bar() { ( : ); }.
kojiro

1
@kojiro nice +1. nie wiedziałem o tym
PSkocik

9

Polecenie z tego przykładu wygląda następująco:

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

Przykład później stwierdza:

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

Będąc charytatywnymi dla ABS Guide, najwyraźniej zamierzali napisać, że funkcja działa wewnątrz podstawienia polecenia, a polecenie wewnątrz podstawienia polecenia działa w podpowłoce .


To bardzo mylące. Dziękuję za twoją interpretację.
Tomasz

5
@tomas „bardzo mylące”. Tak, bardzo. W przeciwieństwie do Przewodnika ABS, Wiki Grega jest doskonałym źródłem zaawansowanych informacji o bashu.
John1024,

1
Twoje zdrowie. Co sądzisz o tym: wiki.bash-hackers.org/start ?
Tomasz

@tomas Nie mam wiedzy z pierwszej ręki na ten temat.
John1024,

2
@tomas, ... moim zdaniem co do wiki bash-hackerów jest to doskonałe źródło. Nie przeszedłem przez to tak kompleksowo, jak mam wiki Wooledge, ale zazwyczaj jest to dokładne i precyzyjnie napisane.
Charles Duffy,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.