while true script read loop for examples example bash while-loop interactive

true - bash: lectura interactiva anidada dentro de un bucle que también usa lectura



while read line bash (2)

Como ya está leyendo todo el archivo en la memoria, léalo en una matriz en lugar de una sola cadena.

# Requires bash 4 or later mapfile -t loop_input < $HOME/.get_iplayer/tv.cache for line in "${loop_input[@]}"; do print_show "$line" read -n 1 -p "do stuff? [y/n] : " resp done

Si todavía usas una versión anterior de bash, aún así recomiendo leer el archivo en una matriz en lugar de una sola cadena, pero es menos conveniente.

declare -a loop_input while read; do loop_input+=("$REPLY"); done for line in "${loop_input[@]}"; do ... done

o, simplemente no puede leer todo el archivo en la memoria:

while read -u 3 line; do .... done 3< $HOME/.get_iplayer/tv.cache

¿Cómo codifica una respuesta interactiva en este ciclo while?

#!/bin/bash shows=$(< ${HOME}/.get_iplayer/tv.cache) # ... # ... stuff with shows omitted ... # ... function print_show { # ... return } while read -r line do print_show "$line" read -n 1 -p "do stuff? [y/n] : " resp # PROBLEM # ... # resp actions omitted # ... done <<< "$shows"

Entonces, un archivo se lee, se "procesa" y luego los datos orientados a la línea resultantes se utilizan en un ciclo de while read simultánea.

Pero la línea de lectura dentro del ciclo while no funciona como se esperaba, es decir, no espera la respuesta del usuario, presumiblemente debido al contexto de while read que está encapsulado.

¿Podría sugerirnos cómo solucionar esto o un mecanismo alternativo?


Has identificado correctamente que la causa es que dentro del

while ...; do ...; done <<< "$shows"

loop, stdin ha sido redirigido, por lo tanto, read ya no se lee desde el teclado.

Puede resolver esto utilizando un descriptor de archivo distinto de 0; por ejemplo,

while read -r -u 3 line; do ...; done 3<${HOME}/.get_iplayer/tv.cache

usará FD 3 para el archivo en lugar de FD 0, permitiendo que la read normal (sin -u ) use stdin original, o

while ...; do read -n 1 -p "do stuff? [y/n] : " -u 3 resp; done 3<&0 <<< "$shows"

para clonar el FD 0 original a FD 3 antes de reemplazar el FD 0 con su cuerda.