Nevyhledávám řešení problému ani řešení. Jsem v pohodě, protože to nefunguje v bash
. Jen nerozumím proč to nefunguje.
Hledám podrobnou odpověď, proč následující skript nefunguje. Všechny předchozí výsledky internetového vyhledávání, včetně příspěvků z unix.stackexchange.com, to úplně nevyřeší. Má to něco společného s read
čtením z stdin
který nefunguje, protože stdin
je již“ převzat „(?) cat
krmením bash
pomocí kanálu?
Příklad bash skriptu test.sh
:
echo "Please say name:" read NAME echo "Hello $NAME"
Metoda 1 volání skriptu s bash test.sh
:
$ bash test.sh Please say name: XYZ Hello XYZ $
Metoda 2 spuštění skriptu pomocí pipingu na bash
:
$ cat test.sh | bash Please say name: $
Takže skript se okamžitě vrátí na výzvu, aniž by čekal na zadání nebo dokonce vytiskl druhou řádek.
Komentáře
Odpověď
Vy četl ze stdin pomocí read
, ale to, co jste četli, byl další řádek standardního vstupu – konkrétně echo "Hello $NAME"
. Po přečtení tohoto řádku již nebyl žádný vstup, a tedy žádné další příkazy k provedení, a skript skončil.
Existuje pouze jeden standardní vstupní proud a vy jste znovu snaží se jej použít pro kód i data. Je to stejné, jako když interaktivní relace bash
čte příkazy z vašeho psaní a také read
odpovědi, stejně jako jakékoli další spuštěné příkazy, pro které chcete použít standardní vstup.
Tuto událost můžete vidět, pokud na konec skriptu přidáme další řádek:
echo "Please say name:" read NAME echo "Hello $NAME" printf "name=%s\n" "$NAME"
Toto poskytuje další příkaz, který umožňuje pokračovat v provádění skriptu, a ukazuje nám, co bylo načteno do NAME
:
Please say name: name=echo "Hello $NAME"
Vidíte, že proměnná obsahuje doslovně to, co bylo napsáno v souboru skriptu – nedošlo k žádné interpolaci, spuštění ani rozšíření proměnné.
Pokud chcete read
z terminálu, je to možné. nejjednodušší způsob, jak pravděpodobně fungovat, je číst ze standardního výstupu namísto standardního vstupu (!), který je pravděpodobně připojen k TTY:
read NAME <&1
This počká, až něco napíšu, a poté přejde na zbytek programu. Můžete také použít /dev/tty
nebo $(tty)
.
Komentáře
- pravděpodobně
read var </dev/tty
by bylo lepší, než předpokládat, že standardní výstup je spojen s vzrušující desítkou.
echo "Hello $NAME"
, poté byl ukončen.