Bash: leer la entrada dentro del ciclo de lectura mientras no funciona

Bash: leer la entrada dentro del ciclo de lectura mientras no funciona

Leer la entrada dentro de un ciclo de lectura while 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 lo haría si la lectura hubiera estado fuera del ciclo. ¿Por qué es esto? ¿Existe alguna solución para leer la entrada dentro de un ciclo de lectura while?

Respuesta1

El problema es que tanto read liney read responseespera (y obtiene) datos de stdin.
Esta preguntaon SO explica parte de esto 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

Respuesta2

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

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

Respuesta3

Gracias Nifle! Y también gracias a bgStack. ¡Después de buscar durante horas finalmente obtuve la respuesta! ¡¡Muy buena!! Utilicé "echo $(tty)" para detectar la ruta de mi terminal o simplemente la tomas como variable. Para mí fue otro caso de uso. Estaba leyendo un archivo y le gustaría confirmar la ejecución. Quizás el siguiente ejemplo ayude 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

Respuesta4

Nifle tiene toda la razón. Sin embargo, cuando utiliza varios terminales, debe ser específico.

Para aquellos de ustedes que vienen de Google, felicidades por encontrar esta página. Si necesita realizar alguna entrada del usuario durante un ciclo de lectura while (esto incluye rm -i, reado cualquier otra cosa), puede especificar qué canal de entrada usar.

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

información relacionada