web-dev-qa-db-fra.com

Lire l'entrée dans bash dans 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 le bon résultat, car lorsque je lis dans la boucle while, il essaie de lire depuis le fichier filename en raison de la redirection possible des E/S.

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

89
w2lame

Lire à partir du terminal de contrôle:

read input </dev/tty

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

94
dank

Vous pouvez rediriger le stdin normal par le biais de l'unité 3 pour le conserver dans le pipeline:

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

En passant, si vous utilisez réellement cat de cette façon, remplacez-le par une redirection et les choses deviendront encore plus simples:

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

Ou, vous pouvez permuter stdin et unité 3 dans cette version - lisez le fichier avec l'unité 3 et laissez stdin seul:

while read line <&3; do
    # read & use stdin normally inside the loop
    read input
    echo "$input"
done 3<notify-finished
52
Gordon Davisson

Essayez de changer la boucle comme ceci:

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

Test de l'unité:

for line in $(cat /etc/passwd); do
    read input
    echo $input;
    echo "[$line]"
done
5
dimba

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

while read input
do
    echo $input
done < filename
4
Hai Vu