V Pokročilé příručce pro skriptování Bash , v příklad 27-4 , 7. řádek zdola, četl jsem toto:
Funkce běží jako dílčí proces.
Provedl jsem test v Bash a zdá se, že výše uvedený výrok je špatný.
Hledá na tento web, Bash Man, a můj vyhledávač nepřinášejí žádné světlo.
Máte odpověď a chtěli byste to vysvětlit?
Komentáře
- Jak je uvedeno, tato příručka je extrémně zavádějící. Místo toho doporučuji Průvodce Wooledge Bash .
- Důležitým faktem je, že " Bash " se vyhýbá vytváření podslun. Jsou drahé, mají vaše vlastní prostředí a ovlivňují výkon skriptu i způsob, jakým kód proudí (mnohokrát, nepohodlně, aby bylo možné vypořádat se s jejich zvláštnostmi). Skutečný stav Bash je produktem evoluce, vývojem kódu. Myslím tím, že první verze Bash používá více subshellů *** než ta skutečná. Tento druh nekonzistence se zdá být rozumný. *** pokud chcete důkaz, nemohu vám ' dát. ' odvodil jsem to z webových stránek, komentářů … <
jsem toto prohlášení někde před nějakou dobou přečetl.
Odpověď
Průvodce Advanced Bash-Scripting Guide není vždy spolehlivý a jeho ukázkové skripty obsahují zastaralé postupy, jako je použití skutečně zastaralé zpětné vazby pro nahrazení příkazů, tj. `command`
místo $(command)
.
V tomto konkrétním případě je to zjevně nesprávné.
Sekce o Shell funkcích v (kanonickém) bashu příručka definitivně uvádí, že
Funkce prostředí jsou prováděny v aktuálním kontextu prostředí; pro jejich interpretaci není vytvořen žádný nový proces.
Komentáře
- " Průvodce pro pokročilé skriptování Bash je obecně nespolehlivý " velmi pravdivý.
- Můžete uvést odkazy na podporu svého první věta?
- @WillVousden, jak by zde vypadal odkaz? Několik příkladů technických nedostatků průvodce '? Dokument, kde odborníci v komunitě bash již dříve poznamenali, že je nespolehlivý? Pomohlo by, kdyby člen stackoverflow se zlatým odznakem v bash právě souhlasil v komentáři? : p
- @WillVousden ' si nemyslím, že to, co chcete, existuje ve spolehlivé formě. Mendel Cooper v minulosti aktualizoval a opravil problémy s průvodcem, ale neexistuje žádný veřejný sledovač chyb ani seznam chyb. (Možná je to ta nejzávažnější výpověď, kterou mohu učinit.) Takže když najdeme chybu (vnímanou nebo skutečnou), můžeme jen zaslat e-mail autorovi a doufat v to nejlepší.
- @WillVousden, .. .pokud chcete historii toho, jak dlouho panuje shoda v kanálu freenode #bash, že je třeba se vyhnout ABS, přečtěte si wooledge.org/ ~ greybot / meta / abs – druhé pole v každém řádku je časové razítko a první je uživatelské jméno; ' Budu doufat, že stačí tvrzení, že dotyčná uživatelská jména jsou velmi respektovaní jednotlivci.
Odpověď
Funkce Curly Brace poběží v procesu volajícího shellu, pokud nepotřebují vlastní subshell, který je:
- když je spustíte na pozadí s
&
- když je spustíte jako odkaz v potrubí
Přesměrování nebo další env. proměnné nevynutí nový subshell:
hw(){ echo hello world from $BASHPID echo var=$var } var=42 hw >&2 echo $BASHPID #unexports var=42 and restores stdout here
Pokud definujete funkci v závorkách namísto curlies:
hw()( echo hello world from $BASHPID ) hw echo $BASHPID
vždy se spustí v novém procesu.
Substituce příkazů $()
také vždy vytvoří procesy v bash (ale ne v ksh, pokud spustíte v něm vestavěné soubory).
Komentáře
- Nevěděl jsem '
f() (...)
je povolen. Existují kromě{...}
a(...)
ještě nějaké další definice? V Bash I ' zatím ne do jiných. - @tomas Můžete použít
function hw { echo hello world; }
syntaxi (není třeba()
pokud zadátefunction
a můžete zadat přesměrování hned po závěrečných}
nebo)
jako vhw(){ echo error; } >&2
. To je ' o tom. - Toto je odpověď, o které jsem okamžitě přemýšlel, a je naprosto správná.Mělo by se o něm hlasovat jako o správné odpovědi.
f()(...)
vždy spustí vlastní prostředí, zatímcof(){...}
nikoli. - Funkce bash NB přijímají libovolné složené příkazy, takže
foo() [[ x = x ]]
je také platná definice funkce. Pokud se však podíváte na funkci stype foo
, uvidíte ', že se stále jedná o syntaktický cukr profoo() { [[ x = x ]]; }
. Totéž platí pro funkce subshellu:bar() ( : )
se stanebar() { ( : ); }
. - @kojiro nice +1. nevěděl ' že
odpověď
Příkaz v otázka z tohoto příkladu vypadá takto:
echo ${arrayZ[@]/%e/$(replacement)}
Následující příklad uvádí:
# $( ... ) is command substitution. # A function runs as a sub-process.
Jako charitativní pro ABS Guide to, co zjevně chtěli napsat, je, že funkce běží uvnitř substituce příkazu a příkaz uvnitř substituce příkazu běží v subshell .
Komentáře
- To je ' velmi zavádějící. Děkujeme za váš výklad.
- @tomas " velmi zavádějící. " Ano, velmi. Na rozdíl od průvodce ABS je Greg ' s Wiki vynikajícím zdrojem pokročilých informací o bash.
- Na zdraví. Jaký je ' váš názor na tento: wiki.bash-hackers.org/start ?
- @tomas Nemám o tom z první ruky žádné znalosti.
- @tomas, … můj vlastní názor na wiki bash-hackerů je, že ' je vynikajícím zdrojem. Ještě jsem to ' neprošel tak komplexně jako já mám Wooledge wiki, ale má tendenci být přesný a přesně napsaný.