bash: nested interactive read within a loop that's also using read
如何在此while循环中编写交互式响应的代码?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #!/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循环中的读取行不能按预期工作,也就是说它不等待用户响应,这可能是因为它被封装在
你能建议如何解决这个问题还是另一种机制?
你已经正确地确定了原因是
1 | while ...; do ...; done <<<"$shows" |
循环,stdin被重定向,因此
您可以使用0以外的文件描述符来解决这个问题;例如,
1 | while read -r -u 3 line; do ...; done 3<${HOME}/.get_iplayer/tv.cache |
将对文件使用fd 3而不是fd 0,允许正常的
1 | while ...; do read -n 1 -p"do stuff? [y/n] :" -u 3 resp; done 3<&0 <<<"$shows" |
将原来的fd 0克隆到fd 3,然后用字符串替换fd0。
由于您已经将整个文件读取到内存中,请将其读取到数组中而不是单个字符串中。
1 2 3 4 5 6 7 | # 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的早期版本,我仍然建议您阅读该文件数组而不是单个字符串,但不太方便。
1 2 3 4 5 6 | declare -a loop_input while read; do loop_input+=("$REPLY"); done for line in"${loop_input[@]}"; do ... done |
或者,您不能将文件全部读取到内存中:
1 2 3 | while read -u 3 line; do .... done 3< $HOME/.get_iplayer/tv.cache |