Kører funktioner som underprocesser i Bash?

I Advanced Bash-Scripting Guide , i eksempel 27-4 , 7. linje fra bunden, jeg har læst dette:

En funktion kører som en underproces.

Jeg lavede en test i Bash, og det ser ud til, at ovenstående udsagn er forkert.

Søger efter dette websted, Bash Man, og min søgemaskine bringer ikke noget lys.

Har du svaret og vil forklare det?

Kommentarer

  • Som nævnt er guiden ekstremt vildledende. Jeg anbefaler Wooledge Bash Guide i stedet.
  • En vigtig kendsgerning er, at ” Bash ” undgår at oprette subshells. De er dyre, har dit eget miljø, og de påvirker scriptets ydeevne såvel som den måde, koden flyder på (mange gange ubelejligt for at håndtere deres særlige forhold). Den faktiske tilstand af Bash er et produkt af en udvikling, en kodeudvikling. Jeg mener, den første version af Bash bruger flere subshells *** end den egentlige. Denne form for inkonsekvens synes at være rimelig. *** hvis du vil have et bevis, kan jeg ‘ ikke give dig. Jeg ‘ har afledt det fra websider, kommentarer … Jeg ‘ har læst denne erklæring et eller andet sted for en gang siden.

Svar

Den avancerede vejledning til Bash-Scripting er ikke altid pålidelig, og dens eksempler på scripts indeholder forældede fremgangsmåder såsom brug af udfasede effektivt backticks til kommandosubstitution, dvs. `command` snarere end $(command).

I dette særlige tilfælde er det åbenlyst forkert.

Afsnittet om Shell-funktioner i (kanonisk) Bash manual angiver endeligt, at

Shell-funktioner udføres i den aktuelle shell-kontekst; der oprettes ingen ny proces for at fortolke dem.

Kommentarer

  • ” Advanced Bash-Scripting Guide er generelt upålidelig ” Meget sandt.
  • Kan du give referencer til støtte for din første sætning?
  • @WillVousden hvordan ser en reference ud her? En masse eksempler på vejledningen ‘ s tekniske mangler? Et dokument, hvor eksperter i bash-samfundet tidligere har bemærket, at det er upålideligt? Ville det hjælpe, hvis et stackoverflow-medlem med et guldmærke i bash bare var enig i en kommentar? : p
  • @WillVousden Jeg tror ikke ‘ Tænk ikke, hvad du vil have, findes i en pålidelig form. Mendel Cooper har tidligere opdateret og løst problemer med guiden, men der er ingen offentlig bug tracker eller liste over fejl. (Måske er det den mest fordømmende erklæring, jeg kan komme med.) Så når vi finder en fejl (opfattet eller reel), kan vi kun sende e-mail til forfatteren og håbe det bedste.
  • @WillVousden, .. .hvis du vil have en historie om, hvor længe konsensus i freenode #bash-kanalen har været, at ABS skal undgås, se wooledge.org/ ~ greybot / meta / abs – det andet felt i hver linje er tidsstemplet, og det første er brugernavnet; Jeg ‘ Jeg håber, at påstanden om, at de pågældende brugernavne er meget respekterede individer, er tilstrækkelig.

Svar

Krøllede afstivningsfunktioner kører inden for den kaldende shell-proces, medmindre de har brug for deres egen subshell, som er:

  • når du kører dem i baggrunden med &
  • når du kører dem som et link i en pipeline

Omdirigeringer eller ekstra env. variabler vil ikke tvinge en ny subshell:

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

Hvis du definerer funktionen med parenteser i stedet for curlies:

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

den kører altid i en ny proces.

Kommandosubstitution $() skaber også altid processer i bash (men ikke i ksh hvis du kører indbyggede i det).

Kommentarer

  • Jeg vidste ikke ‘ ikke vidste f() (...) er tilladt. Er der andre definitioner bortset fra {...} og (...)? I Bash er jeg ‘ er ikke i andre endnu.
  • @tomas Du kan bruge function hw { echo hello world; } syntaksen (intet behov for () hvis du skriver function og du kan angive omdirigeringer lige efter den sidste } eller ) som i hw(){ echo error; } >&2. At ‘ handler om det.
  • Dette er det svar, jeg straks tænkte på, og det er helt korrekt.Det skal stemmes som det rigtige svar. f()(...) udfører altid en egen shell, mens f(){...} ikke gør det.
  • NB bash-funktioner accepterer enhver sammensat kommando, så foo() [[ x = x ]] er også en gyldig funktionsdefinition. Men hvis du ser på funktionen med type foo vil du ‘ se, at dette stadig er syntaktisk sukker til foo() { [[ x = x ]]; }. Det samme gælder for subshell-funktioner: bar() ( : ) bliver bar() { ( : ); }.
  • @kojiro nice +1. vidste ‘ ikke det

Svar

Kommandoen i spørgsmål fra dette eksempel ser ud som:

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

Eksemplet siger senere:

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

At være velgørende til ABS Guide, hvad de tilsyneladende mente at skrive, er at funktionen kører inde i en kommandosubstitution og kommandoen inde i en kommandosubstitution kører i en subshell .

Kommentarer

  • At ‘ er meget vildledende. Tak for din fortolkning.
  • @tomas ” meget vildledende. ” Ja, meget. I modsætning til ABS-guiden er Greg ‘ s Wiki en fremragende kilde til avanceret bash-information.
  • Skål. Hvad ‘ er din mening om denne: wiki.bash-hackers.org/start ?
  • @tomas Jeg har ingen førstehånds kendskab til den.
  • @tomas, … min egen mening med hensyn til bash-hackers wiki er, at den ‘ er en fremragende kilde. Jeg har ikke ‘ ikke været igennem det så omfattende som jeg har Wooledge wiki, men det har tendens til at være nøjagtigt og præcist skrevet.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *