0

busybox version 1.33.0

I'm trying to copy the entire home folder.

Inside of home, /dev/sda2/ is mounted, like so:

/home/user/sda2
/home/user/sda2/root
/home/user/sda2/home_backup

Above you can see the root/ directory within sda2/, owned by actual root. Also, there is home_backup/ which will store files from /home.

My issue is:

After executing the following line I get a nice list of files, and /home/user/sda2 and its contents are nowhere to be found, which is what I wanted:

LC_ALL=C find /home -path /home/user/sda2 -prune -o -iname '*' -print \;

But with the following, I always get the operation not permitted error for directory root/ (is accurate, I'm not the owner, a regular user), meaning that it doesn't prune sda2 as I expected:

LC_ALL=C find /home -path /home/user/sda2 -prune -o -iname '*' -exec cp -r '{}' /home/user/sda2/home_backup/ ;/

For obvious reasons /home/user/sda2 must be excluded, to not copy the same data over and over.

Checking this doesn't really answer my question but it gave me a notion on how prune works.

https://stackoverflow.com/questions/1489277/how-to-use-prune-option-of-find-in-sh/1489405#1489405

EDIT

I just realized that with the previous line all files will be all mixed up under home_backup but that's not an issue, I still want to know why I can't "prune" properly.

1 Answer 1

3

There are several issues with your commands. However the most significant is that you're doing a cp -r.
The command find /home ... -iname '*' is going to match every file and directory, including /home itself. So it's going to run cp -r /home /home/user/sda2/home_backup/, which is then going to include that mount.

There is no sane way to do this with find. Basically you're using the wrong tool for the job. Use rsync. Pass the -x option to tell it to not recursively copy the mount.

rsync -aHAXx /home /home/user/sda2/home_backup

If for some reason, you can't use rsync and/or you really want to use find, then you have to do this in multiple steps.

Your first step you need to create the directory structure:

find /home -mount -type d -execdir mkdir -p /home/user/sda2/home_backup/{} \;

Note the use of -mount instead of -prune. You could use -prune, but -mount is simpler. Also note the use of -execdir. This is so that {} is replaced with a relative path, and not an absolute path. If you want /home/user/sda2/home_backup/home/..., then you can use -exec.

Then you need to copy the files

find /home -mount \! -type d -execdir cp -a {} /home/user/sda2/home_backup/{} \;

Note here that to match files, we're instead matching everything other than directories. This is so that non-files, like symlinks and pipes are copied.

You could merge these into a single find command, but that just makes it messier.

All these little nuances are why rsync is a much better option.

2
  • Thank you, so far rsync is not available on the sytem. I might try to add it later on. At this moment what I'm trying is to limit the maxdepth option. Basically I want to keep the files structure.
    – abacox
    Jan 19, 2022 at 3:48
  • 1
    You can't. Not sanely anyway. If you want insane then you need to do it in 2 steps. First find all directories, and then run mkdir inside your backup path to create them. Then find all files, and copy them (without -r). Your prune is fine. Though -mount or -xdev would be a better option.
    – phemmer
    Jan 19, 2022 at 3:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .