Hva er kommandosubstitusjon i et skall? [duplikat]

Dette spørsmålet har allerede svar her :

Kommentarer

  • OK, alle må slappe av og slutte å beskylde hverandre for trolling. Hvis du ikke liker ', kan du nedstemme eller ignorere det og gå bort . Hvis du føler at du ' blir angrepet i kommentarer, så ikke engasjer deg, men flagg og gå bort .
  • Også relatert: Hva ' er forskjellen mellom $ (stuff) og `stuff ?
  • Viser utdata fra en kommando ved bruk av kommandosubstitusjon og echo er et dårlig eksempel på kommandosubstitusjon fordi 1) utdata ville ha blitt vist uansett, 2) printf er tryggere å bruke for variable data. Eksemplet kan like godt skrives date | sed 's/^/Today is /'
  • @Kusalananda Jeg ser poenget ditt med at du skriver ut det umiddelbart (med printf ) er ubrukelig. Jeg endret formuleringen litt, fra umiddelbart til sometime later, er det mer tiltalende?
  • Eksemplet kan være thedate=$(date), etterfulgt av printf 'The date is %s\n' "$thedate".

Svar

" Kommandosubstitusjon " er navnet på funksjonen til skallspråket som lar deg utføre en kommando og få utgangen til den kommandoen erstattet ( erstatte) teksten til kommandoen.

Det er ingen andre funksjoner i skallspråket som lar deg gjøre det.

En kommandosubstitusjon, dvs. hele $(...) uttrykk, erstattes med utdata, som er den primære bruken av kommandosubstitusjoner.

Kommandoen kommandosubstitusjonen utfører, utføres i en subshell, som betyr at det har sitt eget miljø som ikke vil påvirke det overordnede skallets miljø.

Ikke alle subshell-henrettelser er kommandosubstitusjoner ugh (se flere eksempler på slutten).

Eksempel som viser at en kommandosubstitusjon utføres i en subshell:

$ s=123 $ echo "hello $( s=world; echo "$s" )" hello world $ echo "$s" 123 

Her, variabel s er satt til strengen 123. På neste linje påkalles echo på en streng som inneholder resultatet av en kommandosubstitusjon. Kommandosubstitusjonen setter s til strengen world og ekko denne strengen. Strengen world er utgangen av kommandoen i kommandosubstitusjonen og dermed, hvis denne ble kjørt under set -x, ville vi se at den andre linjen ovenfor ville blitt utvidet til echo "hello world", som produserer hello world på terminalen:

$ set -x $ echo "hello $( s=world; echo "$s" )" ++ s=world ++ echo world + echo "hello world" hello world 

(bash legger til et ekstra nivå på + ber om hvert nivå av en kommandosubstitusjonsunderskall i sporingsutgangen, andre skjell kan ikke gjøre dette)

Til slutt viser vi at kommandoen inne i kommandosubstitusjonen ble kjørt i sin egen subshell, fordi den ikke påvirket verdien av s i det anropende skallet (verdien av s er fortsatt 123, ikke world).

Det er andre situasjoner der kommandoer utføres i subshells, for eksempel i

echo "hello" | read message 

I bash, med mindre du angir lastpipe -alternativet (bare i ikke-interaktive forekomster), blir read utført i en subshell, som betyr at $message ikke blir endret i det overordnede skallet, dvs. å gjøre echo "$message" etter kommandoen ovenfor vil ekko en tom streng (eller hvilken som helst verdi $message var før).

En prosessubstitusjon i bash kjøres også i en subshell:

cat < <( echo "hello world" ) 

Også dette skiller seg fra en kommandosubstitusjon.

Kommentarer

  • For bash 4.2 opp, hvis shopt lastpipe er satt, jobbkontroll ikke er aktiv, og rørledningen ikke er bakgrunn, kjører den siste kommandoen ikke i en subshell.
  • Du sier, «Det er ingen andre funksjoner i skallspråket som lar deg gjøre det.» Vel, med fare for å dele håret, kan du gjøre cmd₁ > myfile / read -r var < myfile / cmd₂ "$var" . Om nødvendig kan du utvide det til å håndtere data med flere linjer.
  • @ G-Man Ja, og du kan også skrive ut et nytt skallskript til en fil og utføre det.Det er ingen andre funksjoner som gir en måte å erstatte et stykke tekst med utdataene fra en kommando.

Svar

a=$(command) 

lagrer resultatverdien til command i variabelen.

Det er egentlig ikke mer til det.

Som en sideanmerkning tror jeg:

a=`command` 

er utfaset og har samme betydning som ovenfor.

Kommentarer

  • resultat her er standardutgangen av kommandoen fjernet fra alle dens etterfølgende nye linje tegn (og noen variasjoner mellom skallene hvis utdataene ikke er tekst). Merk at `...` er Bourne av csh-syntaks mens $(...) er Korn / POSIX-syntaksen (med `...` støttes fremdeles for bakoverkompatibilitet)
  • @St é phaneChazelas Takk for verdifull informasjon, og rediger gjerne svaret for å inkludere det.

Legg igjen en kommentar

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