6

如何在这个 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 循环中的 read 行没有按预期工作,即它不等待用户响应,大概是由于while read它封装的上下文。

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

4

2 回答 2

9

您已正确确定原因是在

while ...; do ...; done <<< "$shows"

循环,标准输入已被重定向,因此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 。

于 2012-07-28T21:08:08.933 回答
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
于 2012-07-28T21:31:37.057 回答