rm 可以递归删除空目录吗?

Whi*_*ger 9 directory alias rm

在旧版本的 Unix 中,rm如果目录为空,该命令将删除目录。来自rm的 Research Unix 第八版手册页:“如果条目是目录,则仅在为空时才将其删除。” 我喜欢这种行为,所以我在我的 中有这个别名/etc/profilealias rm='rm -d'我使用的是 GNU coreutils 版本rm,其中-d告诉rm继续并删除目录,如果它们是空的。

到现在为止还挺好。这个别名让我可以rm像过去一样使用。但是,我想更进一步。我想要rm即使目录包含其他目录,也可以删除目录,只要目录是唯一存在的目录。目录结构有多深并不重要,只要那里没有任何文件,只是空的(一旦你到达底部)目录,我想rm将它们全部删除。

这可以写成一个别名,它仍然可以用作常规rm并删除传递给它的任何文件吗?

Gil*_*il' 8

您想遍历目录树并查看它是否包含目录以外的任何内容。这超出了rm的能力。您需要其他工具,例如find. 您可以通过这种方式删除给定目录下的空目录(-depth也会导致删除空的父目录):

find "$x" -depth -type d -exec rmdir {} +
Run Code Online (Sandbox Code Playgroud)

这是一个函数,对于每个参数,如果它是非目录文件或不包含目录以外的任何内容的目录树,则删除该参数。请注意,此函数不是原子的:如果其中一个参数在运行时发生更改,您最终可能会收到一条错误消息,但它不会删除作为参数传递的目录中的任何非目录,这是安全的。

rm () {
  ret=0
  for x; do
    case $x in -*) x=./$x;; esac
    if [ -d "$x" ]; then
      if [ -n "$(find "$x" ! -type d | head -n 1)" ]; then
        echo 1>&2 "$x: non-empty directory tree"
        ret=2
      else
        find "$x" -depth -exec rmdir {} +
        if [ -d "$x" ]; then ret=2; fi
      fi
    else
      command rm "$x" || [ $ret -gt 1 ] || ret=2
    fi
  done
  return $ret
}
Run Code Online (Sandbox Code Playgroud)