Unix & Linux Asked by Koen G. on November 21, 2021
I’m trying to recursively delete a directory with rm -rf
, but this fails because some inner directories don’t have the w
permission set. I know how to fix this with chmod
. However, this requires to iterate over the whole directory twice, which can be slow.
Is there a way to remove such a directory in one go? (Assuming you have enough permissions to give yourself enough permissions)
sudo
is not an option (limited user on pc in question).
I did not do performance measurements. I just guess it makes sense to delete all the files immediately when a directory is read (because it is read completely anyway and you might risk losing already read metadata from the page cache with -depth
) and change the permissions of those 1st level subdirectories then for which that is necessary. With lots of files and subdirectories it seems hard to avoid reading the same directory content again and without the files that should be much faster.
I suggest to use a wrapper script which is called for each directory. That script makes 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"
And run this with
deletion.sh /start/dir
You need rm -r
afterwards as the above approach does not delete the directories (and cannot do so in a useful (i.e. faster than rm -r
) way IMHO).
Independently of the command approach it may help to increase the filesystem commit time. So for ext4
:
mount -o remount,commit=60 /path/to/mp
Answered by Hauke Laging on November 21, 2021
You can run a small shell in each directory to change its mode and delete its contents:
find . -depth -type d -exec sh -c 'echo "Removing $1 contents"; chmod +w "$1" ; rm -r "$1"/*' anything {} ;
Answered by xenoid on November 21, 2021
rsync
with an empty dummy directory seems fine:
mkdir empty; rsync -r --delete empty/ targetdir/; rmdir empty targetdir
With a 10x repeated test on a simple example, this took 10-14s (14 was an outlier, all others took 10 or 11s),
vs. chmod -R u+w targetdir && rm -rf targetdir
, which took 19-25s
and find targetdir -type d -exec chmod 755 {} ; && rm -rf targetdir
, which took 12-16s but will likely deteriorate more than rsync with more complex folder structures.
Answered by Koen G. on November 21, 2021
find directory -type d -exec chmod 775 {} ;
rm -rf directory
Answered by Artem S. Tashkinov on November 21, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP