Вложенный оператор чтения приводит к бесконечному циклу в bash

awkдля строк после (, но не включая )первое совпадение с шаблоном

Если строка, содержащая триггерный шаблон, эквивалентна «CUT HERE», вы можете опустить ее в распечатке:

echoer | awk 'flag ; /pattern/ { flag=1 }'

Каждая строка ввода проходит через два компонента кода awk. Первый компонент — flag, который awk интерпретирует как «вывести строку, если переменная flagне равна нулю». Поскольку переменные awk по умолчанию равны 0, изначально ничего не будет напечатано.

Второй компонент, /pattern/ { flag=1 }, устанавливает флаг в 1, как только обнаруживает шаблон, и флаг сохраняет это значение до конца выполнения.

К тому времени, когда шаблон впервые обнаружен, возможность напечатать эту строку ввода уже упущена. Любые последующие строки (, включая дополнительные строки, содержащие шаблон ), будут напечатаны.

0
25.05.2020, 17:18
2 ответа

readчитает со стандартного ввода, поэтому оба этих readбудут считываться с вывода echoчерез тот же канал, открытый на их стандартном вводе.

Чтобы readвнутри цикла считывалось со стандартного ввода вне канала, вы можете сделать:

foo () {
  printf 'a\nb\nc\n' |
    while IFS= read -r conflicted_file; do
      printf '%s\n' "$conflicted_file"
      while true; do
        IFS= read <&3 -re -p ">  " yn
        case $yn in
            [nN]* ) echo "success"; break;;
            [yY]* ) echo "fail"; break;;
            * ) echo "invalid input";;
        esac
      done
    done
} 3<&0

То есть продублировать его на fd 3 для всего тела функции foo.

2
18.03.2021, 23:32

Операция «чтение» пытается читать из канала вместо tty. Есть несколько решений для этого.

  1. Выполнить read... </dev/tty. Это работает до тех пор, пока не ожидается, что ваша функция foo ()будет иметь перенаправленный ввод.
  2. Перенаправить канал на другой файловый дескриптор и зациклить его чтение, чтобы не повлиять на внутренний вызов чтения.

    Что-то вроде:

    exec 3< <(echo "a\nb\nc")
    
    while read -u 3 conflicted_file; do
      ...
       read -e -p  ">  " yn
      ...
    done
    
    exec 3>&-
    
2
18.03.2021, 23:32

Теги

Похожие вопросы