Funcțiile rulează ca subprocese în Bash?

În Advanced Bash-Scripting Guide , în exemplu 27-4 , a 7-a linie de jos, am „citit acest lucru:

O funcție rulează ca un sub-proces.

Am făcut un test în Bash și se pare că afirmația de mai sus este greșită.

Căutări pe acest site, Bash Man, și motorul meu de căutare nu aduc nicio lumină.

Aveți răspunsul și doriți să explicați?

Comentarii

  • După cum sa menționat, acest ghid este extrem de înșelător. Recomand Ghidul Wooledge Bash .
  • Un fapt important este că ” Bash ” evită crearea de sub-shell-uri. Sunt scumpe, au propriul mediu și acestea afectează performanța scriptului, precum și modul în care codul curge (de multe ori, incomod, pentru a face față particularităților lor). Starea reală a lui Bash este un produs al unei evoluții, o evoluție a codului. Adică, prima versiune a lui Bash folosește mai multe sub-shell *** decât cea reală. Acest tip de inconsecvență pare a fi rezonabil. *** dacă doriți o dovadă, nu vă pot ‘ să vă dau. ‘ l-am derivat din pagini web, comentarii … Am ‘ am citit acea afirmație undeva în urmă.

Răspuns

Advanced Bash-Scripting Guide nu este întotdeauna fiabil și scripturile sale de exemplu conțin practici învechite, cum ar fi utilizarea efectiv depreciate backticks pentru substituirea comenzii, adică `command` mai degrabă decât $(command).

În acest caz particular, este flagrant incorect.

Secțiunea despre Funcții Shell din Bash (canonic) manualul afirmă definitiv că

Funcțiile Shell sunt executate în contextul shell actual; nu este creat nici un proces nou pentru a le interpreta.

Comentarii

  • ” Advanced Bash-Scripting Guide nu este, în general, de încredere ” Foarte adevărat.
  • Puteți da referințe pentru a vă prima teză?
  • @WillVousden cum ar arăta o referință aici? O grămadă de exemple ale deficiențelor tehnice ale ghidului ‘? Un document în care experții din comunitatea bash au remarcat anterior că nu este de încredere? Ar ajuta dacă un membru stackoverflow cu o insignă de aur în bash tocmai a fost de acord într-un comentariu? : p
  • @WillVousden Nu ‘ nu cred că ceea ce doriți există într-o formă de încredere. Mendel Cooper a actualizat și a remediat problemele cu ghidul în trecut, dar nu există niciun tracker public de erori sau o listă de erori. (Poate că aceasta este cea mai condamnabilă afirmație pe care o pot face.) Așadar, atunci când găsim un defect (perceput sau real) tot ce putem face este să trimitem un e-mail autorului și să sperăm în cele mai bune.
  • @WillVousden, .. .dacă doriți un istoric cu cât a fost consensul în canalul freenode #bash că ABS ar trebui evitat, consultați wooledge.org/ ~ greybot / meta / abs – al doilea câmp din fiecare linie este marca de timp, iar primul este numele de utilizator; ‘ sper să afirm că este suficientă afirmația că numele de utilizator în cauză sunt persoane foarte bine respectate.

Răspuns

Funcțiile curbate vor fi executate în cadrul procesului shell apelant, cu excepția cazului în care au nevoie de propriul subshell care este:

  • când le rulați în fundal cu &
  • când le rulați ca link într-o conductă

Redirecții sau env. variabilele câștigate „nu forțează un sub-shell nou:

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

Dacă definiți funcția cu paranteze în loc de curlie:

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

va rula întotdeauna într-un proces nou.

Înlocuirea comenzii $() creează întotdeauna procese în bash (dar nu în ksh dacă rulați încorporate în interiorul acestuia).

Comentarii

  • Nu ‘ nu știam f() (...) este permis. Există alte definiții în afară de {...} și (...)? În Bash, I ‘ nu sunt încă în altele.
  • @tomas Puteți utiliza sintaxa function hw { echo hello world; } (nu este nevoie de () dacă tastați function și puteți specifica redirecționări imediat după } sau ) ca în hw(){ echo error; } >&2. Aceasta este ‘ despre aceasta.
  • este răspunsul la care m-am gândit imediat și este absolut corect.Ar trebui votat ca răspuns corect. f()(...) execută întotdeauna un shell propriu, în timp ce f(){...} nu.
  • Funcțiile bash NB acceptă orice comandă compusă, deci foo() [[ x = x ]] este și o definiție validă a funcției. Cu toate acestea, dacă te uiți la funcția cu type foo, vei ‘ vei vedea că acesta este în continuare zahăr sintactic pentru foo() { [[ x = x ]]; }. Același lucru este valabil și pentru funcțiile subshell: bar() ( : ) devine bar() { ( : ); }.
  • @kojiro nice +1. ‘ nu știam că

Răspunde

Comanda din întrebarea din acest exemplu arată:

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

Exemplul afirmă mai târziu:

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

Fiind caritabile pentru ABS Guide, ceea ce se pare că au menit să scrie este că funcția rulează în interiorul unei substituiri de comenzi și comanda din interiorul unei înlocuiri de comenzi rulează într-o subshell .

Comentarii

  • ‘ este foarte înșelător. Vă mulțumim pentru interpretare.
  • @tomas ” foarte înșelător. ” Da, foarte. Spre deosebire de Ghidul ABS, Greg ‘ s Wiki este o sursă excelentă de informații bash avansate.
  • Noroc. Ce ‘ este părerea ta despre aceasta: wiki.bash-hackers.org/start ?
  • @tomas Nu am cunoștință directă a aceleia.
  • @tomas, … propria mea părere cu privire la wiki-ul bash-hackers este că ‘ este o sursă excelentă. ‘ nu am trecut prin el la fel de cuprinzător ca și wiki-ul Wooledge, dar tinde să fie corect și precis scris.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *