Nem keresek megoldási lehetőségeket vagy megoldásokat a problémára. Jól vagyok, ha nem úgy működik, mint a bash
. Csak azt nem értem, hogy miért nem működik.
Mélyreható választ keresek arra, hogy miért nem működik a következő szkript. Az összes korábbi internetes keresési eredmény, beleértve az unix.stackexchange.com bejegyzéseit, “nem igazán tisztázható ki teljesen. Van valami köze a read
stdin
amely nem működik, mert a stdin
-t már” elvette “(?) cat
bash
a csövön keresztül?
Példa bash szkriptre test.sh
:
echo "Please say name:" read NAME echo "Hello $NAME"
1. módszer a szkript meghívása a következővel: bash test.sh
:
$ bash test.sh Please say name: XYZ Hello XYZ $
2. módszer a parancsfájl futtatása a bash
:
$ cat test.sh | bash Please say name: $
Tehát a parancsfájl azonnal visszatér a parancssorba, anélkül, hogy megvárná a bevitelt, vagy akár ki is nyomtatná a másodikat sor.
Megjegyzések
Válasz
Ön olvasott a stdin-ből read
-vel, de amit olvasott, az a következő szabványos bemenet sora volt: echo "Hello $NAME"
. Miután elolvasta ezt a sort, nem volt több bevitel, ezért nem volt további végrehajtandó parancs, és a parancsfájlnak vége lett.
Csak egy normál bemeneti adatfolyam van, és Ön megpróbálja használni mind a kódhoz, mind az adatokhoz. Ez megegyezik azzal, ahogy az interaktív bash
munkamenet olvassa a gépelésből származó parancsokat, valamint a read
válaszok, valamint bármely más futtatott parancs normál bevitelt akar használni.
Láthatja, hogy ez történik, ha egy extra sort adunk a szkript végéhez:
echo "Please say name:" read NAME echo "Hello $NAME" printf "name=%s\n" "$NAME"
Ez egy további parancsot nyújt a parancsfájl végrehajtásának folytatásához, és megmutatja, mi olvasható be NAME
:
Please say name: name=echo "Hello $NAME"
Láthatja, hogy a változó szó szerint tartalmazza a szkriptfájlba írtakat – nem történt változó interpoláció, végrehajtás vagy bővítés.
Ha a terminálról read
szeretne, akkor lehetséges. A legegyszerűbb módja annak, hogy valószínűleg a szabványos kimenetről olvasunk be a standard bemenet helyett (!), amely feltehetően a TTY-hez kapcsolódik:
read NAME <&1
Ez megvárja, hogy begépeljek valamit, majd folytatom a program többi részével. Használhatja a következőt is: /dev/tty
vagy $(tty)
.
Megjegyzések
- vitathatatlanul
read var </dev/tty
jobb lenne, mintha azt feltételeznénk, hogy az stdout kapcsolódik az összehúzódó tty-hez.
echo "Hello $NAME"
, majd leállt.