Bash: leer la entrada mientras el ciclo de lectura no funciona

14

La lectura de entrada dentro de un ciclo de lectura de tiempo no parece funcionar

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

la ejecución no se detiene como si la lectura hubiera estado fuera del ciclo. ¿Por qué es esto? ¿Hay alguna solución para leer la entrada dentro de un ciclo while read?

Bueno en realidad
fuente

Respuestas:

15

El problema es que tanto read liney read responseespera (y obtiene) datos de stdin.
Esta pregunta sobre SO explica algunas de ellas con un enlace a aún más información.

tl; dr
La respuesta aceptada sugiere:

Leer desde el dispositivo terminal de control: read input </dev/tty

Nifle
fuente
16

deje que el comando de lectura interno use stdin y use un descriptor de archivo diferente para el ciclo while

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

Nifle lo tiene exactamente bien. Sin embargo, cuando usa múltiples terminales, debe ser específico.

Para aquellos de ustedes que vienen de google, felicidades por encontrar esta página. Si lo que necesita hacer ninguna entrada del usuario durante un bucle de lectura, mientras que (esto incluye rm -i, reado cualquier otra cosa), se puede especificar el tubo de entrada para su uso.

Aquí hay un fragmento de esta solución que utilicé:

#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
bgStack15
fuente
1

Gracias Nifle! Y también gracias a bgStack. ¡Después de buscar durante horas finalmente obtuve la respuesta! ¡¡Muy buena!! Usé "echo $ (tty)" para detectar mi ruta de terminal o simplemente lo tomas como variable. Para mí fue otro caso de uso. U estaba leyendo un archivo y quisiera confirmar la ejecución. Tal vez el siguiente ejemplo ayuda a alguien más.

#!/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
Micha
fuente
En mi caso tuve whilela lectura de una pipa ... y luego utilicé redirección de leer de la entrada estándar: read something < %terminal.
eftshift0