Draaien functies als subprocessen in Bash?

In Advanced Bash-Scripting Guide , in voorbeeld 27-4 , 7-de regel van onderen, ik “heb dit gelezen:

Een functie wordt uitgevoerd als een subproces.

Ik heb een test gedaan in Bash, en het lijkt erop dat de bovenstaande verklaring onjuist is.

Zoekt op deze site, Bash Man, en mijn zoekmachine brengen geen licht.

Heb je het antwoord en wil je het uitleggen?

Reacties

  • Zoals opgemerkt, is die gids uiterst misleidend. Ik raad in plaats daarvan de Wooledge Bash Guide aan.
  • Een belangrijk feit is dat ” Bash ” vermijdt het maken van subshells. Ze zijn duur, hebben uw eigen omgeving, en die hebben invloed op de prestaties van het script en op de manier waarop de code stroomt (vaak, lastig, om met hun bijzonderheden om te gaan). De feitelijke toestand van Bash is een product van een evolutie, een code-evolutie. Ik bedoel, de eerste versie van Bash gebruikt meer subshells *** dan de eigenlijke. Dit soort inconsistentie lijkt redelijk te zijn. *** als je een bewijs wilt, kan ik je ‘ niet geven. Ik ‘ heb het afgeleid van webpaginas, opmerkingen … Ik ‘ heb die verklaring ergens een tijdje geleden gelezen.

Answer

De Advanced Bash-Scripting Guide is niet altijd betrouwbaar en de voorbeeldscripts bevatten verouderde praktijken zoals het gebruik van de heeft effectief afgekeurd backticks voor het vervangen van commandos, dwz `command` in plaats van $(command).

In dit specifieke geval is het ronduit onjuist.

De sectie over Shell-functies in de (canonieke) Bash handleiding stelt definitief dat

Shell-functies worden uitgevoerd in de huidige shell-context; er wordt geen nieuw proces gemaakt om ze te interpreteren.

Reacties

  • ” Advanced Bash-Scripting Guide is over het algemeen onbetrouwbaar ” Zeer waar.
  • Kunt u referenties geven om uw eerste zin?
  • @WillVousden hoe zou een referentie er hier uitzien? Een aantal voorbeelden van de technische tekortkomingen van de gids ‘ s? Een document waarin experts in de bash-gemeenschap eerder hebben opgemerkt dat het onbetrouwbaar is? Zou het helpen als een stackoverflow-lid met een gouden badge in bash het gewoon eens was in een opmerking? : p
  • @WillVousden Ik denk niet ‘ niet dat wat je wilt zelf in een betrouwbare vorm bestaat. Mendel Cooper heeft in het verleden problemen met de gids bijgewerkt en opgelost, maar er is geen openbare bug-tracker of lijst met errata. (Misschien is dat de meest vernietigende verklaring die ik kan afleggen.) Dus als we een (waargenomen of echte) fout vinden, kunnen we alleen de auteur een e-mail sturen en er het beste van hopen.
  • @WillVousden, .. . als je een geschiedenis wilt van hoe lang de consensus in het freenode #bash-kanaal is dat het ABS moet worden vermeden, zie wooledge.org/ ~ greybot / meta / abs – het tweede veld in elke regel is het tijdstempel en het eerste is de gebruikersnaam; Ik ‘ m ga hopen dat de bewering dat de gebruikersnamen in kwestie zeer gerespecteerde individuen zijn, volstaat.

Antwoord

Accolade-functies worden uitgevoerd binnen het aanroepende shell-proces, tenzij ze hun eigen subshell nodig hebben, namelijk:

  • wanneer je ze op de achtergrond uitvoert met &
  • wanneer u ze als een link in een pijplijn uitvoert

Omleidingen of extra omgeving. variabelen zullen “geen nieuwe subshell forceren:

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

Als u de functie definieert met haakjes in plaats van curlies:

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

het zal altijd in een nieuw proces worden uitgevoerd.

Opdrachtvervanging $() creëert ook altijd processen in bash (maar niet in ksh als je voert er ingebouwde functies in).

Reacties

  • Ik heb ‘ niet weten f() (...) is toegestaan. Zijn er andere definities dan {...} en (...)? In Bash, I ‘ m niet in anderen.
  • @tomas Je kunt de function hw { echo hello world; } syntaxis gebruiken (() als u function typt en u kunt omleidingen direct na de laatste } of ) zoals in hw(){ echo error; } >&2. Dat ‘ gaat erover.
  • Dit is het antwoord waar ik meteen aan dacht, en het is absoluut correct.Er moet worden gestemd als het juiste antwoord. f()(...) voer altijd een eigen shell uit, terwijl f(){...} dat niet doet.
  • NB bash-functies accepteren elk samengesteld commando, dus foo() [[ x = x ]] is ook een geldige functiedefinitie. Als je echter naar de functie kijkt met type foo, zul je ‘ zien dat dit nog steeds syntactisch suiker is voor foo() { [[ x = x ]]; }. Hetzelfde geldt voor subshell-functies: bar() ( : ) wordt bar() { ( : ); }.
  • @kojiro leuke +1. wist niet ‘ dat weet ik niet

Antwoord

Het commando in vraag uit dat voorbeeld ziet er als volgt uit:

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

In het voorbeeld staat later:

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

Omdat ze liefdadig zijn voor ABS Guide, wilden ze blijkbaar schrijven dat de functie wordt uitgevoerd binnen een opdrachtvervanging en de opdracht binnen een opdrachtvervanging wordt uitgevoerd in een subshell .

Reacties

  • Dat ‘ is erg misleidend. Bedankt voor je interpretatie.
  • @tomas ” erg misleidend. ” Ja, heel. In tegenstelling tot de ABS-gids is Greg ‘ s Wiki een uitstekende bron van geavanceerde bash-informatie.
  • Proost. Wat is ‘ is jouw mening over deze: wiki.bash-hackers.org/start ?
  • @tomas Ik heb daar geen kennis van uit de eerste hand.
  • @tomas, … mijn eigen mening over de bash-hackers-wiki is dat het ‘ is een uitstekende bron. Ik heb het ‘ niet zo uitgebreid doorgenomen als de Wooledge-wiki, maar het is meestal nauwkeurig en precies geschreven.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *