Bash: lire l'entrée dans la boucle de lecture ne fonctionne pas


14

La lecture de l'entrée dans une boucle de lecture en temps ne semble pas fonctionner

while read line
do
 echo "get some input from the user"
 read response
done < some_file.txt

l'exécution ne s'arrête pas comme si la lecture avait été effectuée en dehors de la boucle. Pourquoi est-ce? Existe-t-il une solution de contournement pour lire les entrées dans une boucle de lecture while?

Réponses:


15

Le problème est qu'à la fois read lineet read responseattend (et obtient) des données de stdin.
Cette question sur SO explique certains d'entre eux avec un lien vers encore plus d'informations.

tl; dr
La réponse acceptée suggère:

Lire depuis le terminal de contrôle: read input </dev/tty


16

laissez la commande de lecture interne utiliser stdin et utilisez un descripteur de fichier différent pour la boucle while

while read -u 3 line; do
  read -p "get some input from the user" response
done 3< some_file.txt

1

Nifle a tout à fait raison. Cependant, lorsque vous utilisez plusieurs terminaux, vous devez être précis.

Pour ceux d'entre vous qui viennent de Google, félicitations pour avoir trouvé cette page. Si vous devez faire une entrée utilisateur pendant un certain temps boucle de lecture (ce qui comprend rm -i, readou quoi que ce soit d' autre), vous pouvez spécifier tuyau d'alimentation à utiliser.

Voici un fragment de cette solution que j'ai utilisée:

#in declarations
thistty=$(tty)

lsuser -R LDAP -a home pgrp ALL 2>/dev/null | while read line
do
   homedir=$(echo $homedir | awk -F= '{print $2}')
   sudo rm -ir "$homedir" < $thistty
done

1

Merci Nifle! Et aussi grâce à bgStack. Après avoir cherché pendant des heures, j'ai finalement obtenu la réponse! Elle est bonne!! J'ai utilisé "echo $ (tty)" pour détecter mon chemin de terminal ou vous le prenez simplement comme variable. Pour moi, c'était un autre cas d'utilisation. U lisait un fichier et voudrait confirmer l'exécution. Peut-être que l'exemple ci-dessous aide quelqu'un d'autre.

#!/bin/bash

export terminal=$(tty)

cat file | while read val1 val2
do
   while true; 
            do
              read -p "would you like to XYZ" yn
              case $yn in
                        [Yy]* )     echo "# Move $val1 to $val2        #";break;;
                        [Nn]* )     echo "#---------no action----------#";break;;
                        * )         echo "# Please answer yes or no.   #";;
              esac
            done < $terminal
done

Dans mon cas , j'avais whilelu à partir d' une pipe ... puis je redirection de lire stdin: read something < %terminal.
eftshift0
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.