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 ループ内の読み取り行は意図したとおりに機能しません。つまり、おそらく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 0 ではなく FD 3 を使用し、通常read( なし-u) で元の stdin を使用できるようにする、または

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 に答える