为何`rm -i`在遍历`find`输出的`while read`循环中失效?如何修复?
问题分析与解决:find管道中rm -i不等待输入直接退出
问题原因
你遇到的核心问题是管道的stdin共享机制在搞怪:
当你用find ... | while read f这种管道结构时,while所在的子shell的标准输入(stdin)被find的输出完全占用了。而rm -i需要从终端读取你的确认输入,但它默认会从当前的stdin读取——这时候stdin里要么是find输出的剩余内容,要么已经读到EOF(文件结束符)了,所以rm根本等不到你的输入,直接就退出了。
顺带提一句,文件名带空格其实和这个问题无关,只是这个场景让你没法照搬ls相关的解决方案而已。
修复方案
给你两种靠谱的解决办法,按需选择:
方法一:用find自带的-exec选项(最推荐)
直接让find调用rm,完全避开管道的stdin问题,还能完美处理带空格的文件名:
find . -name "*.txt" -exec rm -i {} +
这里的{} +表示把找到的所有文件名一次性传给rm,效率更高;如果想逐个文件确认处理,把+换成\;就行:
find . -name "*.txt" -exec rm -i {} \;
方法二:给rm重定向stdin到终端
如果一定要保留管道+while循环的结构,那可以强制让rm从终端(而非管道)读取输入,把rm的stdin重定向到/dev/tty:
find . -name "*.txt" | while read f; do /bin/rm -i "$f" < /dev/tty; done
这样rm就会直接从你的终端读取确认输入,不会再去读管道里的内容,自然就能正常等待你的输入了。
内容的提问来源于stack exchange,提问作者MWB
相关产品推荐
相关产品推荐

