I Advanced Bash-Scripting Guide , i eksempel 27-4 , syvende linje fra bunnen, jeg har lest dette:
En funksjon kjører som en underprosess.
Jeg gjorde en test i Bash, og det ser ut til at utsagnet ovenfor er feil.
Søker på dette nettstedet, Bash Man, og søkemotoren min gir ikke noe lys.
Har du svaret og vil forklare det?
Kommentarer
- Som nevnt, er guiden ekstremt misvisende. Jeg anbefaler Wooledge Bash Guide i stedet.
- Et viktig faktum er at » Bash » unngår å lage subshells. De er dyre, har ditt eget miljø, og de påvirker skriptets ytelse og måten koden flyter på (mange ganger, ubeleilig, for å håndtere deres særegenheter). Den faktiske tilstanden til Bash er et produkt av en evolusjon, en kodeutvikling. Jeg mener, den første versjonen av Bash bruker flere subshells *** enn den faktiske. Denne typen inkonsekvens ser ut til å være rimelig. *** Hvis du vil ha et bevis, kan jeg ‘ ikke gi deg. Jeg ‘ har hentet det fra websider, kommentarer … Jeg ‘ har lest utsagnet et sted for en gang siden.
Svar
Advanced Bash-Scripting Guide er ikke alltid pålitelig, og eksemplene på skriptene inneholder utdaterte fremgangsmåter som å bruke utrangerte backticks effektivt for kommandosubstitusjon, dvs. `command`
i stedet for $(command)
.
I dette tilfellet er det åpenbart feil.
Avsnittet om Shell-funksjoner i (kanonisk) Bash håndboken sier definitivt at
Shell-funksjoner kjøres i gjeldende shell-kontekst; ingen nye prosesser blir opprettet for å tolke dem.
Kommentarer
- » Advanced Bash-Scripting Guide er generelt upålitelig » Veldig sant.
- Kan du gi referanser for å støtte din første setning?
- @WillVousden hvordan ville en referanse se ut her? En haug med eksempler på guiden ‘ s tekniske mangler? Et dokument der eksperter i bash-samfunnet tidligere har lagt merke til at det er upålitelig? Ville det hjelpe hvis et stackoverflow-medlem med et gullmerke i bash bare var enig i en kommentar? : p
- @WillVousden Jeg tror ikke ‘ Jeg tror ikke det du vil eksistere i en pålitelig form. Mendel Cooper har tidligere oppdatert og løst problemer med guiden, men det er ingen offentlig bug tracker eller liste over feil. (Kanskje det er den mest fordømmende uttalelsen jeg kan komme med.) Så når vi finner en feil (oppfattet eller reell), er alt vi kan gjøre å sende forfatteren på e-post og håpe på det beste.
- @WillVousden, .. .hvis du vil ha en historie om hvor lenge konsensus i freenode #bash-kanalen har vært at ABS skal unngås, se wooledge.org/ ~ greybot / meta / abs – det andre feltet i hver linje er tidsstempelet, og det første er brukernavnet; Jeg ‘ skal håpe at påstanden om at brukernavnene det er snakk om er veldig respekterte individer, er tilstrekkelig.
Svar
Krøllete avstivningsfunksjoner vil kjøres innen den anropende skallprosessen, med mindre de trenger sitt eget subshell som er:
- når du kjører dem i bakgrunnen med
&
- når du kjører dem som en lenke i en rørledning
Omdirigeringer eller ekstra env. variabler vil ikke tvinge et nytt 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 funksjonen med parenteser i stedet for curlies:
hw()( echo hello world from $BASHPID ) hw echo $BASHPID
den vil alltid kjøre i en ny prosess.
Kommandosubstitusjon $()
oppretter også alltid prosesser i bash (men ikke i ksh hvis du kjører innebygde inne i den).
Kommentarer
- Jeg visste ikke ‘ visste ikke
f() (...)
er tillatt. Er det noen andre definisjoner bortsett fra{...}
og(...)
? I Bash, I ‘ er ikke i andre ennå. - @tomas Du kan bruke
function hw { echo hello world; }
syntaksen (ikke behov for()
hvis du skriverfunction
og du kan spesifisere omdirigeringer rett etter den endelige}
eller)
som ihw(){ echo error; } >&2
. At ‘ handler om det. - Dette er svaret jeg umiddelbart tenkte på, og det er helt riktig.Det skal stemmes som riktig svar.
f()(...)
utfører alltid et eget skall, mensf(){...}
ikke gjør det. - NB bash-funksjoner godtar en sammensatt kommando, så
foo() [[ x = x ]]
er også en gyldig funksjonsdefinisjon. Men hvis du ser på funksjonen medtype foo
vil du ‘ se at dette fortsatt er syntaktisk sukker forfoo() { [[ x = x ]]; }
. Det samme gjelder subshell-funksjoner:bar() ( : )
blirbar() { ( : ); }
. - @kojiro fin +1. visste ‘ ikke det
Svar
Kommandoen i spørsmålet fra det eksemplet ser slik ut:
echo ${arrayZ[@]/%e/$(replacement)}
Eksemplet sier senere:
# $( ... ) is command substitution. # A function runs as a sub-process.
Å være veldedig mot ABS Guide, det de tilsynelatende mente å skrive, er at funksjonen kjører i en kommandosubstitusjon og kommandoen inne i en kommandosubstitusjon kjører i en subshell .
Kommentarer
- At ‘ er veldig misvisende. Takk for tolkningen din.
- @tomas » veldig misvisende. » Ja, veldig. I motsetning til ABS-guiden er Greg ‘ s Wiki en utmerket kilde til avansert bash-informasjon.
- Skål. Hva ‘ er din mening om denne: wiki.bash-hackers.org/start ?
- @tomas Jeg har ingen førstehåndskunnskap om den.
- @tomas, … min egen mening om bash-hackers wiki er at den ‘ er en utmerket kilde. Jeg har ikke ‘ ikke vært gjennom det så omfattende som jeg har Wooledge-wiki, men det pleier å være nøyaktig og presist skrevet.