eval vs pipe through bash

Hva er forskjellen mellom å bruke:

eval "echo "foo"" 

og

echo "echo "foo"" | bash 

er det noen?

Kommentarer

  • Her er ' en annen variant med litt annen oppførsel med hensyn til utførelsesmiljøer: ( eval 'echo "foo"' )

Svar

Kort svar

Kommandoen som kjøres av eval kjøres i gjeldende skall og kommandoen som ledes til bash utføres i et underskall, f.eks:

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

Lengre svar

I kommentarene ble kravet fremsatt om at i nyere versjoner av bash (> = 4.2) kan den første kommandoen også ha samme effekt. Dette ser imidlertid ikke ut til å være tilfelle.

Det er faktisk et par faktorer som gjør at den pipede kommandoen ikke kjører i den gjeldende økten: røret og bash kommando.

For det meste kjøres rørkommandoer i subshells. Bash Manual ( Seksjon 3.2.2: Rørledninger ) har følgende å si:

Hver kommando i en rørledning utføres i sin egen subshell (se Command Execution Environment ).

Som påpekt i kommentarene, kan denne oppførselen endres via alternativet lastpipe. Bash Manual ( Seksjon 4.3.2: The Shopt Builtin ) har følgende å si om lastpipe -alternativet:

siste rør

Hvis angitt, og jobbkontroll ikke er aktiv, kjører skallet den siste kommandoen til en rørledning som ikke er utført i bakgrunn i det nåværende skallmiljøet.

Vi kan bekrefte at dette er tilfelle som følger.

Først aktiver lastpipe:

> shopt -s lastpipe 

Deaktiver deretter jobbkontroll:

> set +m 

Utfør nå en kommando som setter en variabel fra et rør:

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

Legg merke til at vi bruker while loop og read kommando som en omgåelse siden eval kommandoen ikke kan lese inngangen fra stdin (kan derfor ikke få innspill fra et rør).

Dette eksemplet viser at den høyeste kommandoen i røret faktisk kan , utføres i gjeldende skall. Dette påvirker imidlertid ikke vårt opprinnelige eksempel. Selv med lastpipe aktivert og jobbkontroll deaktivert, får vi fremdeles følgende resultat når vi går til bash:

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

Dette er fordi kommandoen bash selv utfører inngangen i en subshell.

Kommentarer

  • det er en god observasjon, skjønte ikke ' det, men ja jeg antar at ' s hvordan rør fungerer
  • Bare nysgjerrig, hva er grunnen til at du ikke godtok svaret?
  • For bash 4.2+ når du kjører et skript (eller mer nøyaktig når jobbkontroll er av) og shopt lastpipe er satt og rørledningen er ikke bakgrunn, den kjører den høyre enden av røret i ' toppen ' skallet ikke et subshell. Se unix.stackexchange.com/questions/9954/… og unix.stackexchange.com/questions/136206/readarray-or-pipe-issue
  • @ dave_thompson_085 Kommandoen bash kan utføres i toppskallet avhengig av alternativer, men x=42 vil helt sikkert kjøres i noe som med rimelighet kan kalles en subshell.
  • @AlexanderMills Egentlig er røret ikke ' t eneste problemet. bash -kommandoen vil utføre inngangen i en subshell uavhengig av om et rør er involvert. Se oppdateringen til løsningen min for mer informasjon.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *