Fungují funkce jako podprocesy v Bash?

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áte function a můžete zadat přesměrování hned po závěrečných } nebo ) jako v hw(){ 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ímco f(){...} 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 s type foo, uvidíte ', že se stále jedná o syntaktický cukr pro foo() { [[ x = x ]]; }. Totéž platí pro funkce subshellu: bar() ( : ) se stane bar() { ( : ); }.
  • @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ý.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *