Lire l'entrée dans bash à l'intérieur d'une boucle while

je vais avoir un script bash qui est quelque chose comme suit,

cat filename | while read line
do
    read input;
    echo $input;
done

mais il est clair que cela ne me donne pas la bonne sortie comme quand je lis dans la boucle while il essaie de lire à partir du nom du fichier en raison de la redirection possible d'e/s.

une autre façon de faire la même chose?

79
demandé sur Stormie 2011-07-30 17:22:39

5 réponses

lire du terminal de commande:

read input </dev/tty

plus d'informations: http://compgroups.net/comp.unix.shell/Fixing-stdin-inside-a-redirected-loop

85
répondu dank 2011-07-30 13:42:48

vous pouvez rediriger le STDIN régulier à travers l'unité 3 pour garder le get it à l'intérieur du pipeline:

{ cat notify-finished | while read line; do
    read -u 3 input
    echo "$input"
done; } 3<&0

BTW, si vous utilisez vraiment cat de cette façon, le remplacer par une redirection et les choses deviennent encore plus faciles:

while read line; do
    read -u 3 input
    echo "$input"
done 3<&0 <notify-finished

ou, vous pouvez échanger stdin et l'unité 3 dans cette version -- lire le fichier avec l'unité 3, et juste laisser stdin seul:

while read line <&3; do
    # read & use stdin normally inside the loop
    read input
    echo "$input"
done 3<notify-finished
47
répondu Gordon Davisson 2018-08-14 14:54:11

Essayez de changer la boucle comme ceci:

for line in $(cat filename); do
    read input
    echo $input;
done

essai unitaire:

for line in $(cat /etc/passwd); do
    read input
    echo $input;
    echo "[$line]"
done
6
répondu dimba 2011-07-30 13:46:57

on dirait que vous avez lu deux fois, la lecture à l'intérieur de la boucle while n'est pas nécessaire. Aussi, vous n'avez pas besoin d'invoquer la commande cat:

while read input
do
    echo $input
done < filename
5
répondu Hai Vu 2011-07-30 13:32:50
echo "Enter the Programs you want to run:"
> ${PROGRAM_LIST}
while read PROGRAM_ENTRY
do
   if [ ! -s ${PROGRAM_ENTRY} ]
   then
      echo ${PROGRAM_ENTRY} >> ${PROGRAM_LIST}
   else
      break
   fi
done
-5
répondu Munchk1n 2014-08-22 07:47:30