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/ttyjobb lenne, mintha azt feltételeznénk, hogy az stdout kapcsolódik az összehúzódó tty-hez.
echo "Hello $NAME", majd leállt.