En etsi kiertotapoja tai ratkaisuja ongelmaan. Hyvin, jos se ei toimi näin bash
. En vain ymmärrä miksi se ei toimi.
Etsin syvällistä vastausta, miksi seuraava komentosarja ei toimi. Kaikkia aiempia Internet-hakutuloksia, mukaan lukien unix.stackexchange.com-sivuston viestit, ei voitu tyhjentää tätä kokonaan. Sillä on jotain tekemistä read
-kohdan kanssa, joka on luettu kohteesta stdin
joka ei toimi, koska stdin
on jo” otettu ”(?) cat
syötteen bash
putken kautta?
Esimerkki bash-komentosarjasta test.sh
:
echo "Please say name:" read NAME echo "Hello $NAME"
Tapa 1 kutsutaan komentosarjaa bash test.sh
:
$ bash test.sh Please say name: XYZ Hello XYZ $
Tapa 2, joka ajaa komentosarjan bash
:
$ cat test.sh | bash Please say name: $
Joten komentosarja palaa välittömästi kehotteeseen odottamatta syötettä tai edes tulostamalla toista rivi.
Kommentit
Vastaa
Sinä luki stdinistä read
, mutta lukemasi oli seuraava vakiosyötön rivi – nimittäin echo "Hello $NAME"
. Kun olet lukenut kyseisen rivin, syötettä ei enää ollut eikä enää komentoja suoritettavaksi, ja komentosarja oli ohi.
Vain yksi vakiosyöttövirta on olemassa, ja olet yritetään käyttää sitä sekä koodiin että tietoihin. Tämä on sama kuin miten vuorovaikutteinen bash
-istunto lukee kirjoittamasi komennot sekä read
vastaukset sekä kaikki muut suorittamasi komennot haluavat käyttää vakiosyöttöä.
Näet tämän tapahtuvan, jos lisäämme ylimääräisen rivin komentosarjan loppuun:
echo "Please say name:" read NAME echo "Hello $NAME" printf "name=%s\n" "$NAME"
Tämä antaa molemmille uuden komennon nähdäksesi komentosarjan suorituksen jatkumisen, ja näyttää meille mitä luettiin NAME
:
Please say name: name=echo "Hello $NAME"
Voit nähdä, että muuttuja pitää sisällään verbatim sen, mikä on kirjoitettu komentosarjatiedostoon – muuttujan interpolointia, suorittamista tai laajentamista ei ole tapahtunut.
Jos haluat read
päätelaitteelta, se on mahdollista. yksinkertaisin tapa, joka todennäköisesti toimii, on lukea vakiolähdöstä vakiotulon (!) sijaan, joka on oletettavasti liitetty TTY: hen:
read NAME <&1
Tämä odottaa minun kirjoittavan jotain ja siirtyy sitten muuhun ohjelmaan. Voit käyttää myös /dev/tty
tai $(tty)
.
Kommentit
- epäilemättä
read var </dev/tty
olisi parempi kuin olettaa, että stdout on kytketty supistuvaan tty: hen.
echo "Hello $NAME"
ja lopetti sitten.