Bash: чтение ввода в то время как цикл чтения не работает

14

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

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

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

а на самом деле
источник

Ответы:

15

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

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

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

Nifle
источник
16

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

while read -u 3 line; do
  read -p "get some input from the user" response
done 3< some_file.txt
Гленн Джекман
источник
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
bgStack15
источник
1

Спасибо, Нифле! А также благодаря 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
Миха
источник
В моем случае я имел whileчтение из трубы ... и затем я использовал перенаправление , чтобы читать из стандартного ввода: read something < %terminal.
eftshift0