Bash 为什么';";rm-i";在一家公司工作;当读到;在“的输出上循环”;找到“;?

Bash 为什么';";rm-i";在一家公司工作;当读到;在“的输出上循环”;找到“;?,bash,Bash,如果我执行 find . -name \*\.txt | while read f; do /bin/rm -i "$f"; done rm询问: /bin/rm:删除常规的空文件“./某些文件名带有空格.txt” 但是命令在没有等待答案的情况下退出。这是为什么?如何解决 关于这个主题的另一个问题是,循环通过ls输出,但在我的例子中,STDIN是find的输出,有多个文件,每个文件中都可能有空格,所以我不能切换到非循环方法。因为rm从循环继承了它的标准输入,它连接到左侧的输出。因此,在read

如果我执行

find . -name \*\.txt | while read f; do /bin/rm -i "$f"; done
rm
询问:

/bin/rm:删除常规的空文件“./某些文件名带有空格.txt”

但是命令在没有等待答案的情况下退出。这是为什么?如何解决


关于这个主题的另一个问题是,循环通过
ls
输出,但在我的例子中,
STDIN
find
的输出,有多个文件,每个文件中都可能有空格,所以我不能切换到非循环方法。

因为
rm
从循环继承了它的标准输入,它连接到左侧的输出。因此,在
read f
获得名称
foo
之后,
rm
就没有什么可以从stdin读取的了。这就是
rm
自动退出的原因

如果需要提示,请不要使用管道。有很多选择。其中之一是

rm -i $(echo foo)

因为
rm
从循环继承其标准输入,循环从左侧连接到输出。因此,在
read f
获得名称
foo
之后,
rm
就没有什么可以从stdin读取的了。这就是
rm
自动退出的原因

如果需要提示,请不要使用管道。有很多选择。其中之一是

rm -i $(echo foo)

使用
find
-exec
操作,而不是在默认的
-print
操作生成的内容上循环:

find . -name \*\.txt -exec rm -i -- {} +
在这个命令中,
{}
表示由
find
迭代的元素,
+
都限定了由
find-exec
执行的命令,并声明它应该一次用尽可能多的元素替换
{}
(或者,您可以使用
\;
对每个元素执行一次命令)。
--
rm-i
之后确保
find
列出的文件不会被解释为
rm
选项(如果它们以破折号开头),而是正确地解释为文件名


这不仅更加简洁(虽然不容易理解),而且还避免了与原始解决方案可能具有的特殊字符相关的问题。

使用
查找
的默认
-print
操作生成的内容,而不是使用
查找
-exec
操作:

find . -name \*\.txt -exec rm -i -- {} +
while IFS= read -r -d '' f <&3; do
  rm -i -- "$f"
done 3< <(find . -name '*.txt' -print0)
在这个命令中,
{}
表示由
find
迭代的元素,
+
都限定了由
find-exec
执行的命令,并声明它应该一次用尽可能多的元素替换
{}
(或者,您可以使用
\;
对每个元素执行一次命令)。
--
rm-i
之后确保
find
列出的文件不会被解释为
rm
选项(如果它们以破折号开头),而是正确地解释为文件名


这不仅更加简洁(尽管不容易理解),但它也避免了与特殊字符相关的问题。天真的解决方案可能会有。

而IFS=read-r-d''f
而IFS=read-r-d''f这是重复的吗?@cnicutar谢谢。我更新了问题。我认为我不能切换到非标准格式的方法,而只是避免问题,就像在另一个问题中一样。这是重复的吗?@cnicutar谢谢。我更新了Q。我不认为我可以切换到非基于标准输入法的方法,只是避免问题,就像在另一个Q中一样。我必须在您键入a时更新了Q。我不认为我可以切换到非循环版本(标准输入法是带有多个文件的
find
的输出,每个文件中都可能有空格)我一定是在你输入A的时候更新了Q。我不认为我可以切换到非循环版本(STDIN是带有多个文件的
find
,每个文件中都可能有空格)我经常看到这一点。与Aaron的答案(这是我自己写的)相比,它似乎过于复杂了.有什么好的理由喜欢这种构造吗?@DevSolar,…Aaron的答案很好,只是更有限——你没有外壳,所以你不能在被处理的项目之间保持状态。如果你在做一些与
rm
不同的事情,那将是你循环中内置的外壳,那么
exec
ing代码可能会有很多erhead.总之,我在这里教授的是更一般的实践。我对任何部分都不感兴趣,我只是好奇它可能比更简单的
find…-exec
有什么实际优势。保持状态是,尽管它不是适用于这个问题的优势。看起来这个答案更一般(不仅仅是对于
find
),另一个对于我的用例来说更简单,所以我接受了它。感谢我一直看到这一点。与Aaron的答案(这是我自己会写的)相比,它似乎过于复杂了.有什么好的理由喜欢这种构造吗?@DevSolar,…Aaron的答案很好,只是更有限——你没有外壳,所以你不能在被处理的项目之间保持状态。如果你在做一些与
rm
不同的事情,那将是你循环中内置的外壳,那么
exec
ing代码可能会有很多erhead.总之,我在这里教授的是更一般的实践。我对任何部分都不感兴趣,我只是好奇它可能比更简单的
find…-exec
有什么实际优势。保持状态是,尽管它不是适用于这个问题的优势。看起来这个答案更一般(不仅仅是对于
find
),对于我的用例,另一个更简单,所以我接受了它。谢谢我建议
rm-I--{}+
--这样,每次调用
rm
while IFS= read -r -d '' f <&3; do
  rm -i -- "$f"
done 3< <(find . -name '*.txt' -print0)