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?

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


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

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

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.