web-dev-qa-db-ja.com

whileループ内でbashで入力を読み取る

私は次のようなものであるbashスクリプトを持っています

cat filename | while read line
do
    read input;
    echo $input;
done

しかし、これは、I/Oリダイレクトの可能性があるため、whileループで読み取るときにファイルfilenameから読み取ろうとするため、明らかに正しい出力が得られません。

同じことをする他の方法はありますか?

89
w2lame

制御端末デバイスから読み取ります。

read input </dev/tty

詳細: http://compgroups.net/comp.unix.Shell/Fixing-stdin-inside-a-redirected-loop

94
dank

ユニット3を介して通常のstdinをリダイレクトして、パイプライン内で取得し続けることができます。

{ cat notify-finished | while read line; do
    read -u 3 input
    echo "$input"
done; } 3<&0

ところで、本当にこのようにcatを使用している場合は、リダイレクトに置き換えれば、さらに簡単になります。

while read line; do
    read -u 3 input
    echo "$input"
done 3<&0 <notify-finished

または、そのバージョンのstdinとunit 3を交換できます。unit3でファイルを読み取り、stdinをそのままにしておきます。

while read line <&3; do
    # read & use stdin normally inside the loop
    read input
    echo "$input"
done 3<notify-finished
52
Gordon Davisson

次のようにループを変更してみてください。

for line in $(cat filename); do
    read input
    echo $input;
done

単体テスト:

for line in $(cat /etc/passwd); do
    read input
    echo $input;
    echo "[$line]"
done
5
dimba

二度読むように見えますが、whileループ内の読み取りは必要ありません。また、catコマンドを呼び出す必要はありません。

while read input
do
    echo $input
done < filename
4
Hai Vu