Nu „caut soluții sau soluții pentru această problemă. Sunt bine că nu funcționează așa în bash
. Pur și simplu nu înțeleg de ce nu funcționează.
Caut un răspuns aprofundat de ce următorul script nu funcționează. Toate rezultatele anterioare ale căutării pe internet, inclusiv postările de pe unix.stackexchange.com, nu au putut clarifica complet acest lucru. Are ceva de-a face cu citirea read
din stdin
care nu funcționează deoarece stdin
este deja” luat „(?) de cat
alimentând bash
prin conductă?
Exemplu de script bash test.sh
:
echo "Please say name:" read NAME echo "Hello $NAME"
Metoda 1 apelând scriptul cu bash test.sh
:
$ bash test.sh Please say name: XYZ Hello XYZ $
Metoda 2 care rulează scriptul prin canalizare către bash
:
$ cat test.sh | bash Please say name: $
Deci, scriptul revine imediat la prompt, fără a aștepta introducerea sau chiar a imprima a doua linie.
Comentarii
Răspuns
Tu a citit din stdin cu read
, dar ceea ce ați citit a fost următoarea linie de intrare standard – și anume echo "Hello $NAME"
. După ce ați citit acea linie, nu a mai existat nicio intrare și, prin urmare, nu au existat alte comenzi de executat, iar scriptul s-a terminat.
Există un singur flux de intrare standard și sunteți re încercând să-l folosiți atât pentru cod, cât și pentru date. Acesta este același lucru cu modul în care o sesiune interactivă bash
citește comenzi din tastarea dvs., precum și read
răspunsuri, precum și orice alte comenzi pe care le executați doresc să utilizeze intrarea standard.
Puteți vedea acest lucru dacă adăugăm o linie suplimentară la sfârșitul scriptului:
echo "Please say name:" read NAME echo "Hello $NAME" printf "name=%s\n" "$NAME"
Ambele oferă o comandă suplimentară pentru a vedea executarea scriptului și ne arată ce a fost citit în NAME
:
Please say name: name=echo "Hello $NAME"
Puteți vedea că variabila conține textual ceea ce a fost scris în fișierul script – nu s-a întâmplat nicio interpolare, execuție sau extindere a variabilei.
Dacă doriți să read
de la terminal, este posibil. cel mai simplu mod în care este posibil să funcționeze este să citiți din ieșirea standard în loc de intrarea standard (!), care este probabil conectată la TTY:
read NAME <&1
mă va aștepta să scriu ceva și apoi să trec la restul programului. De asemenea, puteți utiliza /dev/tty
sau $(tty)
.
Comentarii
- probabil
read var </dev/tty
ar fi mai bine decât să presupunem că stdout este conectat la tty-ul contraceptiv.
echo "Hello $NAME"
, apoi a fost terminată.