読み取りループ中に対話型入力を取得する際に問題があります。

読み取りループ中に対話型入力を取得する際に問題があります。

私は以下の最小限の例を実行しています。

#! /bin/sh

# $1 = file containing list of files to sync
# $2 = source dir ; $3 = target dir

cat "$1" | while read f
do
    cp -i "$2"/"$f" "$3"/"$f"
done

私はそれがcp -i私の入力をまったく待たずにループが最後まで実行されたことを発見しました。なぜ?この状況を解決するためにどのような措置を講じることができますか?

ベストアンサー1

ここまで掘ってみるとわかるhttps://unix.stackexchange.com/a/56877/54067(質問と回答の表現が異なり、質問は対話型入力とは関係ありません。)問題の原因は、ユーザーがパイプを介してcp -i対話型入力検証を提供する必要がありますが、ループがパイプによって使用されてstdinいるためです。入力ファイルの次の行はユーザー入力と見なされます。cat | while readstdin

したがって、このソリューションは他の質問で提案されているものと似ています。次のファイルディスクリプタを介してコンテンツを転送しますstdin

while read f <&3
do
    cp -i "$2"/"$f" "$3"/"$f"
done 3< "$1"

ループの上部と下部に、とが表示されています<&33< "$1"

他の質問に答えてくれた@StéphaneChazelasに感謝します。 (私は賛成に投票しました。)

また、明らかにここにこれを投稿すると、他にインタラクティブな入力ソリューションがあるかどうか疑問に思います。

また、for他のqと同様にループを使用できますが、ファイルが非常に大きい場合、ファイルを内部で拡張して不要なメモリを消費することが$(cat "$1")心配されます。for f in "$(cat "$1")"OTOHパイプラインはIIUCを1行ずつ読み取る必要があります。だから私は使用するforことが有効な解決策だとは思わない。私もこれについてコメントしたい。

おすすめ記事