bash:在也使用read的循环中嵌套的交互式读取

时间:2012-07-28 20:19:44

标签: bash while-loop interactive

如何在此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上下文。

您能否建议如何解决此问题或替代机制?

2 个答案:

答案 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