如何在此while循环中编写交互式响应代码?
#!/bin/bash
shows=$(< ${HOME}/.get_iplayer/tv.cache)
# ...
# ... stuff with shows omitted ...
# ...
function print_show {
# ...
return
}
while read -r line
do
print_show "$line"
read -n 1 -p "do stuff? [y/n] : " resp # PROBLEM
# ...
# resp actions omitted
# ...
done <<< "$shows"
所以读取一个文件,“处理”然后在while read
循环中使用生成的面向行的数据
但是while循环中的读取行不能按预期工作,也就是说它不等待用户响应,可能是由于它被封装的while read
上下文。
您能否建议如何解决此问题或替代机制?
答案 0 :(得分:4)
您已正确识别原因是
中的原因while ...; do ...; done <<< "$shows"
循环,stdin已被重定向,因此read
不再从键盘读取。
您可以使用0以外的文件描述符来解决此问题;例如,
while read -r -u 3 line; do ...; done 3<${HOME}/.get_iplayer/tv.cache
将FD 3用于文件而不是FD 0,允许正常read
(不-u
)使用原始标准输入,或
while ...; do read -n 1 -p "do stuff? [y/n] : " -u 3 resp; done 3<&0 <<< "$shows"
在用你的字符串替换FD 0之前将原始FD 0克隆到FD 3。
答案 1 :(得分:1)
由于您已经将整个文件读入内存,因此请将其读入数组而不是单个字符串。
# Requires bash 4 or later
mapfile -t loop_input < $HOME/.get_iplayer/tv.cache
for line in "${loop_input[@]}"; do
print_show "$line"
read -n 1 -p "do stuff? [y/n] : " resp
done
如果您仍然使用早期版本的bash,我仍然建议您阅读该文件 到数组而不是单个字符串,但它不太方便。
declare -a loop_input
while read; do loop_input+=("$REPLY"); done
for line in "${loop_input[@]}"; do
...
done
或者,您可以不将文件全部读入内存:
while read -u 3 line; do
....
done 3< $HOME/.get_iplayer/tv.cache