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


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

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.