Kommentarer
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.
echoer et dårlig eksempel på kommandosubstitusjon fordi 1) utdata ville ha blitt vist uansett, 2)printfer tryggere å bruke for variable data. Eksemplet kan like godt skrivesdate | sed 's/^/Today is /'printf) er ubrukelig. Jeg endret formuleringen litt, fra umiddelbart tilsometime later, er det mer tiltalende?thedate=$(date), etterfulgt avprintf 'The date is %s\n' "$thedate".