我正在尝试使用 递归删除目录rm -rf
,但这失败了,因为某些内部目录没有w
设置权限。我知道如何解决这个问题chmod
。但是,这需要对整个目录进行两次迭代,这可能会很慢。
有没有办法一次性删除这样的目录? (假设您有足够的权限给自己足够的权限)
sudo
不是一个选项(相关电脑上的受限用户)。
答案1
rsync
使用空的虚拟目录似乎没问题:
mkdir empty; rsync -r --delete empty/ targetdir/; rmdir empty targetdir
在一个简单的示例上进行 10 次重复测试,这需要 10-14 秒(14 是异常值,所有其他值需要 10 或 11 秒),
而 则chmod -R u+w targetdir && rm -rf targetdir
需要 19-25 秒
,而find targetdir -type d -exec chmod 755 {} \; && rm -rf targetdir
则需要 12 秒-16s,但可能会比具有更复杂文件夹结构的 rsync 恶化更多。
答案2
find directory -type d -exec chmod 775 {} \;
rm -rf directory
答案3
我没有进行性能测量。我只是猜想在读取目录时立即删除所有文件是有意义的(因为无论如何它都会被完全读取,并且您可能会冒着丢失已从页面缓存中读取的元数据的风险-depth
)并更改这些第一级子目录的权限,然后对其进行更改这是必要的。对于大量文件和子目录,似乎很难避免再次读取相同的目录内容,而没有文件应该会更快。
我建议使用为每个目录调用的包装脚本。该脚本使find
- 删除参数目录中的所有文件
- 必要时修复一级子目录的权限
- 为每个一级子目录调用脚本
#!/bin/bash
set -x
dir_path="$1"
test -d "$dir_path" || exit 1
declare -i tests_x=0
declare -i tests_x_limit=30
while true; do
# there is a race condition between the -exec + and xargs
if [ -x "$dir_path" ]; then
break
else
sleep 1
fi
tests_x+=1
if [ "$tests_x" -gt "$tests_x_limit" ]; then
exit 1
fi
done
find "$dir_path" -mindepth 1 -maxdepth 1 -type f -delete -o -type l -delete \
-o -\( -type d ! -perm -700 -exec chmod u=rwx {} + , -print0 \) |
xargs -0 -n 1 -r "$0"
并运行它
deletion.sh /start/dir
您rm -r
之后需要,因为上述方法不会删除目录(并且不能以有用(即比更快rm -r
)的方式删除目录,恕我直言)。
独立于命令方法,它可能有助于增加文件系统提交时间。因此对于ext4
:
mount -o remount,commit=60 /path/to/mp
答案4
您可以在每个目录中运行一个小 shell 来更改其模式并删除其内容:
find . -depth -type d -exec sh -c 'echo "Removing $1 contents"; chmod +w "$1" ; rm -r "$1"/*' anything {} \;