중첩된 읽기 문으로 인해 Bash에서 무한 루프가 발생합니다.

중첩된 읽기 문으로 인해 Bash에서 무한 루프가 발생합니다.

명령에서 파일 목록을 읽고 사용자에게 각 파일에 대한 입력을 요청하려고 합니다. 하나는 파일 이름을 읽는 데 사용 read하고 다른 하나는 사용자 입력을 가져오는 데 사용하고 있지만 이 스크립트는 무한 루프에 빠지는 것 같습니다.

foo () {
echo "a\nb\nc" | while read conflicted_file;
do
    echo $conflicted_file
    while true; do
        read -e -p ">  " yn
        case $yn in
            [nN]* ) echo "success"; break;;
            [yY]* ) echo "fail"; break;;
            * ) echo "invalid input";;
        esac
    done
done;
}

foo

외부 레이어를 제거하는 것이 while read트릭을 수행하는 것 같습니다. 어떤 아이디어가 있나요?

답변1

read표준 입력에서 읽으므로 두 s 모두 read표준 입력에서 열린 동일한 파이프를 통해 출력에서 ​​읽습니다.echo

read파이프 외부의 stdin에서 루프 내부를 읽으 려면 다음을 수행할 수 있습니다.

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

즉, foo함수 본문 전체의 fd 3에 복사합니다.

답변2

"읽기" 작업은 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>&-
    

관련 정보