eval vs. pipe through bash (Čeština)

Jaký je rozdíl mezi použitím:

eval "echo "foo"" 

a

echo "echo "foo"" | bash 

existují?

Komentáře

  • Zde ' další variace s poněkud odlišným chováním v prostředí provádění: ( eval 'echo "foo"' )

odpověď

krátká odpověď

Příkaz spuštěný eval se provádí v aktuálním prostředí a příkaz předaný do bash se provádí v dílčím prostředí, např .:

> echo "x=42" | bash; echo $x > eval "x=42"; echo $x 42 

Delší odpověď

V komentářích bylo vzneseno tvrzení, že v novějších verzích bash (> = 4,2) první příkaz může mít také stejný účinek. Zdá se však, že tomu tak není.

Ve skutečnosti existuje několik faktorů, které způsobují, že se příkaz piped v aktuální relaci nespustí: kanál a bash příkaz.

Piped příkazy se většinou spouštějí v dílčích skořápkách. Manuál Bash ( Oddíl 3.2.2: Potrubí ) má toto:

Každý příkaz v kanálu se provádí ve svém vlastním subshellu (viz Prostředí pro provádění příkazů ).

Jak bylo uvedeno v komentářích, toto chování lze upravit pomocí možnosti lastpipe. Manuál Bash ( Oddíl 4.3.2: Sestavený obchod ) má o možnosti lastpipe říci toto:

lastpipe

Pokud je nastaveno a řízení úloh není aktivní, prostředí spustí poslední příkaz potrubí, které se v pozadí v aktuálním prostředí prostředí.

Můžeme ověřit, že tomu tak je, následujícím způsobem.

Nejprve povolte lastpipe:

> shopt -s lastpipe 

Poté deaktivujte řízení úloh:

> set +m 

Nyní spusťte příkaz, který nastaví proměnnou z potrubí:

> unset x > echo x=42 | while IFS= read -r line; do eval "${line}"; done; > echo $x 42 

Všimněte si, že používáme while loop a read příkaz jako řešení, protože příkaz eval nemůže číst jeho vstup ze stdin (tedy nemůže získat jeho vstup z potrubí).

Tento příklad ukazuje, že příkaz zcela vpravo ve kanálu může ve skutečnosti být , být provedeny v aktuálním prostředí. To však ve skutečnosti neovlivní náš původní příklad. I když je lastpipe povoleno a zakázáno řízení úloh, při piping na bash stále máme následující výsledek:

> echo "x=42" | bash; echo $x > 

Důvodem je, že samotný příkaz bash provádí svůj vstup v subshellu.

Komentáře

  • to je dobrý postřeh, neuvědomil jsem si to ', ale myslím, že ' Jak fungují roury
  • Jen jsem zvědavý, jaký je důvod, proč jste odpověď nepřijali?
  • Pro bash 4.2+ při spuštění skriptu (nebo přesněji, když je jobcontrol vypnutý) a shopt lastpipe je nastaven a potrubí není na pozadí, vede pravý konec kanálu v ' nahoru ' shell není subshell. Viz unix.stackexchange.com/questions/9954/… a unix.stackexchange.com/questions/136206/readarray-or-pipe-issue
  • @ dave_thompson_085 Příkaz bash lze spustit v horní shell v závislosti na možnostech, ale x=42 bude jistě spuštěn v něčem, co lze rozumně nazvat subshell.
  • @AlexanderMills Ve skutečnosti potrubí není ' jediný problém. Příkaz bash provede svůj vstup v subshell bez ohledu na to, zda se jedná o rouru. Další podrobnosti najdete v aktualizaci mého řešení.

Napsat komentář

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