명령에서 파일 목록을 읽고 사용자에게 각 파일에 대한 입력을 요청하려고 합니다. 하나는 파일 이름을 읽는 데 사용 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 대신 파이프에서 읽기를 시도합니다. 이에 대한 몇 가지 해결책이 있습니다.
- 달리기
read ... </dev/tty
. 이는 foo() 함수가 입력 리디렉션을 기대하지 않는 한 작동합니다. 파이프를 다른 파일 설명자로 리디렉션하고 해당 파일 설명자를 반복하여 내부 읽기 호출이 영향을 받지 않도록 합니다.
그것은 다음과 같습니다:
exec 3< <(echo "a\nb\nc") while read -u 3 conflicted_file; do ... read -e -p "> " yn ... done exec 3>&-