Czy funkcje działają jako podprocesy w Bash?

W Advanced Bash-Scripting Guide , w przykład 27-4 , siódma linia od dołu, przeczytałem to:

Funkcja działa jako podproces.

Wykonałem test w Bash i wygląda na to, że powyższe stwierdzenie jest błędne.

Wyszukiwania na ta witryna, Bash Man, i moja wyszukiwarka nie dają żadnego światła.

Czy masz odpowiedź i chcesz wyjaśnić?

Komentarze

  • Jak zauważono, ten przewodnik jest skrajnie mylący. Zamiast tego polecam Przewodnik po basach wełnianych .
  • Ważnym faktem jest to, że ” Bash ” unika tworzenia podpowłok. Są drogie, mają własne środowisko, a te wpływają na wydajność skryptu, a także sposób, w jaki kod przepływa (wielokrotnie, niewygodnie, aby poradzić sobie z ich specyfiką). Aktualny stan Bash jest wynikiem ewolucji, ewolucji kodu. Chodzi mi o to, że pierwsza wersja Bash używa więcej podpowłok *** niż rzeczywista. Ten rodzaj niespójności wydaje się uzasadniony. *** jeśli potrzebujesz dowodu, ' nie dam ci. ' wyprowadziłem je ze stron internetowych, komentarzy … ' czytałem to stwierdzenie gdzieś temu.

Odpowiedź

Advanced Bash-Scripting Guide nie zawsze jest wiarygodny, a jego przykładowe skrypty zawierają przestarzałe praktyki, takie jak używanie faktycznie wycofane odwrócone znaki do podstawiania poleceń, tj. `command` zamiast $(command).

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

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

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

Komentarze

  • ” Podręcznik zaawansowanego skryptowania Bash jest ogólnie zawodny ” Bardzo prawdziwe.
  • Czy możesz podać referencje wspierające pierwsze zdanie?
  • @WillVousden jak wyglądałoby tutaj odniesienie? Kilka przykładów niedociągnięć technicznych ' przewodnika? Dokument, w którym eksperci ze społeczności bash wcześniej zauważyli, że jest zawodny? Czy pomogłoby, gdyby członek stackoverflow ze złotą odznaką w bash właśnie zgodził się w komentarzu? : p
  • @WillVousden Nie ' nie sądzę, że to, czego chcesz, istnieje w niezawodnej formie. Mendel Cooper zaktualizował i naprawił problemy z przewodnikiem w przeszłości, 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ę złożyć). Więc kiedy znajdziemy usterkę (domniemaną lub prawdziwą), jedyne, co możemy zrobić, to wysłać e-mail do autora i mieć nadzieję na najlepsze. . jeśli chcesz poznać historię , jak długo na kanale freenode #bash panowało przekonanie, że ABS należy unikać, zobacz wooledge.org/ ~ greybot / meta / abs – drugie pole w każdej linii to znacznik czasu, a pierwsze to nazwa użytkownika; ' Mam nadzieję, że wystarczy zapewnienie, że nazwy użytkowników, o których mowa, są bardzo szanowanymi osobami.

Odpowiedź

Funkcje nawiasów klamrowych będą działały wewnątrz wywołującego procesu powłoki, chyba że potrzebują własnej podpowłoki, czyli:

  • gdy uruchamiasz je w tle z &
  • , gdy uruchamiasz je jako łącze w potoku

Przekierowania lub dodatkowe środowisko. zmienne nie „nie wymuszają 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 zdefiniujesz funkcję za pomocą nawiasów zamiast curlies:

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

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

Zastępowanie poleceń $() również zawsze tworzy procesy w bash (ale nie w ksh, jeśli uruchamiasz w nim wbudowane).

Komentarze

  • Nie ' nie wiem jest dozwolone. Czy istnieją inne definicje oprócz {...} i (...)? W Bash, ja ' nie jestem jeszcze w innych.
  • @tomas Możesz użyć składni function hw { echo hello world; } (nie ma potrzeby stosowania , jeśli wpiszesz function i możesz określić przekierowania zaraz po ostatnim } lub ) jak w hw(){ echo error; } >&2. To ' o tym.
  • To to odpowiedź, o której od razu pomyślałem i jest całkowicie poprawna.Powinien zostać uznany za poprawną odpowiedź. f()(...) zawsze wykonuje własną powłokę, podczas gdy f(){...} nie.
  • NB funkcje bash akceptują dowolne polecenia złożone, więc foo() [[ x = x ]] to również poprawna definicja funkcji. Jeśli jednak spojrzysz na funkcję z type foo, ' zobaczysz, że to wciąż cukier składniowy dla foo() { [[ x = x ]]; }. To samo dotyczy funkcji podpowłoki: bar() ( : ) staje się bar() { ( : ); }.
  • @kojiro nice +1. nie ' nie wiem, że

Odpowiedź

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

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

Przykład później brzmi:

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

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

Komentarze

  • To ' jest bardzo mylące. Dziękuję za interpretację.
  • @tomas ” bardzo mylące. ” Tak, bardzo. W przeciwieństwie do przewodnika ABS, Greg ' s Wiki jest doskonałym źródłem zaawansowanych informacji o bashu.
  • Pozdrawiam. Jaka ' jest Twoja opinia na temat tego: wiki.bash-hackers.org/start ?
  • @tomas Nie znam go z pierwszej ręki.
  • @tomas, … moja własna opinia na temat wiki bash-hackerów jest taka, że ' jest doskonałym źródłem. Nie ' nie przeszedłem przez to tak kompleksowo, jak w przypadku wiki Wooledge, ale wydaje się, że jest dokładny i precyzyjnie napisany.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *