我试图了解如何将 stdout 用作另一个命令的 stdin。为了测试它,我尝试使用以下命令从当前文件夹中删除所有目录。
ls -d -- */ | rm -rf $1
我希望 ls -d -- */ 的结果能够通过管道传输到 rm 的输入中,但是它不起作用。有什么想法吗?
答案1
并非所有命令/程序都会直接接受管道输入(包括)。另外,为什么在脚本之外rm
使用 bash 替换变量?$1
对于一般情况,您需要查看xargs
,这是一个实用程序,其目标是通过从 stdin 获取列表,然后使用该列表的元素(以不同的可能方式)调用命令来简化此类场景。
对于您想要做的事情...(明智地使用它!):(rm -rf *
或.
)就足够了。
答案2
find -maxdepth 1 -not -name ".*" -type d -print0 | xargs -n1 -0 rm -rf
-maxdepth 1
仅包括当前目录。-not -name ".*"
排除隐藏目录。-type d
仅包括目录,不包括文件。find -print0
与一起使用xargs -0
将使用名称带有奇怪字符的文件和目录。xargs -n1
一次执行一行命令(在本例中为 rm)。
答案3
两个选项:
ls -d -- */ | xargs rm -r
或者
rm -r `ls -d -- */`
过去,xargs 是必需的,因为命令行参数列表有限制。xargs 会为每次执行设置一个合理的数字,并多次运行给定的命令(它还有一些很酷的东西可以帮助您进行并发执行)。然而,在最近的内核中,这个限制已经消失,因此更简单的没有管道的 rm 命令可以正常工作,尽管它会占用更多的 RAM,因此如果有成千上万个参数,xargs 仍然会更高效。
值得注意的是,您不需要-f
rm,因为只有当文件不存在时您希望 rm 继续,或者跳过任何交互式确认时才需要它。由于您有 ls 告诉您它们存在,所以最好不要使用它,然后通常的别名-i
将使您免于意外删除写保护的文件和目录。
答案4
在这种特定情况下,您还可以使用find
:
find . -maxdepth 1 -type -d -exec rm -rf {} \;