Je « ne cherche pas de solution de contournement ou de solution au problème. Je » suis daccord avec le fait que cela ne fonctionne pas comme ça dans bash
. Je ne comprends simplement pas pourquoi ça ne marche pas.
Je cherche une réponse détaillée pourquoi le script suivant ne fonctionne pas. Tous les résultats de recherche Internet précédents, y compris les publications de unix.stackexchange.com, n’ont pas pu clarifier complètement ce point. Cela a quelque chose à voir avec la lecture read
de stdin
qui ne fonctionne pas car stdin
est déjà » pris « (?) par cat
alimentant bash
via le tube?
Exemple de script bash test.sh
:
echo "Please say name:" read NAME echo "Hello $NAME"
Méthode 1 appelant le script avec bash test.sh
:
$ bash test.sh Please say name: XYZ Hello XYZ $
Méthode 2 exécutant le script via piping vers bash
:
$ cat test.sh | bash Please say name: $
Le script revient donc immédiatement à linvite, sans attendre lentrée ni même imprimer la seconde ligne.
Commentaires
Réponse
Vous lu depuis stdin avec read
, mais ce que vous avez lu était la ligne suivante de lentrée standard – à savoir echo "Hello $NAME"
. Après avoir lu cette ligne, il ny avait plus dentrée et donc plus de commandes à exécuter, et le script était terminé.
Il ny a quun flux dentrée standard, et vous « re essayez de lutiliser à la fois pour le code et les données. Cela revient à la façon dont une session bash
interactive lit les commandes de votre saisie, ainsi que read
, ainsi que toutes les autres commandes que vous exécutez pour lesquelles vous souhaitez utiliser lentrée standard.
Vous pouvez voir que cela se produit si nous ajoutons une ligne supplémentaire à la fin du script:
echo "Please say name:" read NAME echo "Hello $NAME" printf "name=%s\n" "$NAME"
Ceci fournit à la fois une commande supplémentaire pour voir le script continuer lexécution et nous montre ce qui a été lu dans NAME
:
Please say name: name=echo "Hello $NAME"
Vous pouvez voir que la variable contient verbatim ce qui a été écrit dans le fichier de script – aucune interpolation, exécution ou expansion de variable ne sest produite.
Si vous souhaitez read
depuis le terminal, cest possible. Le moyen le plus simple qui est susceptible de fonctionner est de lire à partir de la sortie standard au lieu de lentrée standard (!), qui est probablement connectée au TTY:
read NAME <&1
Ceci attendra que je tape quelque chose, puis passera au reste du programme. Vous pouvez également utiliser /dev/tty
ou $(tty)
.
Commentaires
- sans doute
read var </dev/tty
serait mieux que de supposer que stdout est connecté au terminal de contrôle.
echo "Hello $NAME"
, puis sest terminé.