我正在做类似以下最小示例的事情:
#! /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
and 。3< "$1"
感谢@StéphaneChazelas 在其他问题中的回答。 (我投了赞成票。)
此外,显然,在这里发布此内容我想知道除此之外是否还有其他交互式输入解决方案。
另请注意,虽然for
像其他 q 中那样使用循环是可能的,但我担心如果文件非常大,则$(cat "$1")
infor f in "$(cat "$1")"
会通过就地扩展文件来消耗不必要的内存。 OTOH 管道应该处理逐行读取 IIUC。所以我不认为使用for
是一个有效的解决方案。我也想对此发表评论。