Kommentit
Vastaa
" Komennon korvaaminen " on shell-kielen ominaisuuden nimi, jonka avulla voit suorittaa komennon ja antaa komennon lähdön korvata ( korvaa) komennon teksti.
Shell-kielellä ei ole muuta ominaisuutta, joka sallisi sinun tehdä sen.
Komennon korvaaminen, ts. koko $(...)
-lauseke, korvataan sen lähdöllä, joka on ensisijainen komentokorvausten käyttö.
Komento, jonka komentokorvaus suorittaa, suoritetaan subhell, mikä tarkoittaa, että sillä on oma ympäristö, joka ei vaikuta vanhemman kuoren ympäristöön.
Kaikki alikuoren suoritukset eivät ole komentojen korvauksia ugh (katso lisää esimerkkejä lopussa).
Esimerkki siitä, että komentokorvaus suoritetaan alikuoressa:
$ s=123 $ echo "hello $( s=world; echo "$s" )" hello world $ echo "$s" 123
Tässä muuttuja s
asetetaan merkkijonoksi 123
. Seuraavalla rivillä echo
kutsutaan merkkijonoon, joka sisältää komennon korvaamisen tuloksen. Komennon korvaaminen asettaa s
merkkijonoksi world
ja toistaa tämän merkkijonon. Merkkijono world
on komennon tulos komentokorvauksessa ja siten, jos tämä suoritettiin kohdassa set -x
, näemme, että yllä oleva toinen rivi olisi laajennettu arvoon echo "hello world"
, joka tuottaa hello world
päätelaitteessa:
$ set -x $ echo "hello $( s=world; echo "$s" )" ++ s=world ++ echo world + echo "hello world" hello world
(bash
lisää ylimääräisen tason +
kehotteet jokaiselle tasolle komennon korvaushakemisto jälkilähdössä, muut kuoret eivät välttämättä tee tätä)
Lopuksi näytämme, että komennon komentokorvauksen sisällä oleva komento suoritettiin omassa alikuoressaan, koska se ei vaikuttanut arvon s
kutsuvassa kuoressa (s
-arvon arvo on edelleen 123
, ei world
).
On muitakin tilanteita, joissa komennot suoritetaan alikuorissa, kuten
echo "hello" | read message
Kohdassa bash
, ellet määritä vaihtoehtoa lastpipe
(vain muissa kuin vuorovaikutteisissa tapauksissa), read
suoritetaan alikuoressa, mikä tarkoittaa että $message
ei muuteta vanhemmassa kuoressa, toisin sanoen tekemällä echo "$message"
sen jälkeen kun yllä oleva komento toistaa tyhjän merkkijonon (tai minkä tahansa arvon $message
oli aiemmin).
Prosessikorvaus bash
-sovelluksessa suoritetaan myös alikuoressa:
cat < <( echo "hello world" )
Tämäkin eroaa komentojen korvaamisesta.
Kommentit
- Jos kyseessä on bash 4.2, jos shopt lastpipe on asetettu, työn hallinta ei ole aktiivinen ja putki ei ole taustalla, viimeinen komento ei toimi alikuoressa.
- Sanot: ”Shell-kielellä ei ole mitään muuta ominaisuutta, joka sallisi sinun tehdä sen.” No, karvojen halkeamisen vaarassa voit tehdä
cmd₁ > myfile
/read -r var < myfile
/cmd₂ "$var"
. Tarvittaessa voit laajentaa sitä käsittelemään monirivisiä tietoja. - @ G-Man Kyllä, ja voit myös kirjoittaa tiedostoon uuden komentotiedoston ja suorittaa sen.Mikään muu ominaisuus ei tarjoa tapaa korvata tekstikappale komennon tuotoksella.
Vastaa
a=$(command)
tallentaa arvon command
muuttujaan.
Siinä ei todellakaan ole muuta.
Lisähuomautuksena uskon:
a=`command`
on poistettu käytöstä ja sillä on sama merkitys kuin yllä.
Kommentit
- tulos tässä on komennon vakiolähtö, josta on poistettu kaikki viimeiset uudet rivit merkkejä (ja joitain muunnelmia kuorien välillä, jos tulosteet ovat ei-teksti). Huomaa, että
`...`
on csh-syntaksin Bourne, kun taas$(...)
on Korn / POSIX-syntaksi (`...`
tukee edelleen taaksepäin tapahtuvaa yhteensopivuutta) - @St é phaneChazelas Kiitos arvokkaasta tiedosta ja voit muokata vastausta lisäämällä siihen vastauksen.
echo
on huono esimerkki komentojen korvaamisesta, koska 1) lähtö olisi joka tapauksessa näytetty, 2)printf
on turvallisempi käyttää muuttuviin tietoihin. Esimerkki voitaisiin yhtä hyvin kirjoittaadate | sed 's/^/Today is /'
printf
) on hyödytön. Vaihdoin muotoilua hieman, heti sanastasometime later
, onko se houkuttelevampi?thedate=$(date)
, jota seuraaprintf 'The date is %s\n' "$thedate"
.