
私は以下の最小限の例を実行しています。
#! /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 read
stdin
したがって、このソリューションは他の質問で提案されているものと似ています。次のファイルディスクリプタを介してコンテンツを転送しますstdin
。
while read f <&3
do
cp -i "$2"/"$f" "$3"/"$f"
done 3< "$1"
ループの上部と下部に、とが表示されています<&3
。3< "$1"
他の質問に答えてくれた@StéphaneChazelasに感謝します。 (私は賛成に投票しました。)
また、明らかにここにこれを投稿すると、他にインタラクティブな入力ソリューションがあるかどうか疑問に思います。
また、for
他のqと同様にループを使用できますが、ファイルが非常に大きい場合、ファイルを内部で拡張して不要なメモリを消費することが$(cat "$1")
心配されます。for f in "$(cat "$1")"
OTOHパイプラインはIIUCを1行ずつ読み取る必要があります。だから私は使用するfor
ことが有効な解決策だとは思わない。私もこれについてコメントしたい。