9

Чтение ввода в течение цикла чтения, кажется, не работает

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

выполнение не приостанавливается, как если бы чтение было вне цикла. Почему это? Есть ли обходной путь для чтения ввода во время цикла чтения?

4 ответа4

13

позвольте внутренней команде чтения использовать stdin и использовать другой дескриптор файла для цикла while

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

Проблема в том, что и read line read response ожидают (и получают) данные из стандартного stdin .
Этот вопрос о SO объясняет некоторые из них ссылкой на еще более подробную информацию.

ТЛ; др
Принятый ответ предполагает:

Чтение с управляющего оконечного устройства: read input </dev/tty

1

У Nifle это совершенно верно. Однако, когда вы используете несколько терминалов, вам нужно быть конкретным.

Для тех из вас, кто пришел из Google, поздравляем с обнаружением этой страницы. Если вам нужно выполнить какой-либо пользовательский ввод во время цикла чтения (включая rm -i , read или что-то еще), вы можете указать, какой канал ввода использовать.

Вот фрагмент этого решения, которое я использовал:

#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
0

Спасибо, Нифле! А также благодаря bgStack. После поиска часов я наконец получил ответ! Великий!! Я использовал "echo $(tty)", чтобы определить мой путь к терминалу, или вы просто используете его как переменную Для меня это был другой вариант использования. U читал файл и хотел бы подтвердить исполнение. Может быть, пример ниже поможет кому-то еще.

#!/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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .