I have the following line in a script to backup and it is not recursively copying all the directories, it gets the files but just lumps them all together. Can anyone tell me what is wrong with it?

find . -type f -not -executable -exec cp -ruv {} /run/media/user/32GB/prog/ \; 

The -exec argument to find simply executes that command on each item returned. So, for example, if you have a directory set like:

>$ find .

The -exec portion will be run once for each line, substituting the text for {}. So, in your case, it would recursively copy each entry to the specified directory.

cp -ruv a.txt /run/media/user/32GB/prog/
cp -ruv b.txt /run/media/user/32GB/prog/
cp -ruv dir1 /run/media/user/32GB/prog/
cp -ruv dir1/c.txt /run/media/user/32GB/prog/
etc, etc

Incidentally, you also mark -not -executable. This makes the real difference. Directories in Linux are executable. (The execute bit on directories manages permissions to list the contents of the directory, since folders can't be executed.)

>$ ls -l
-rw-rw-r--.   1 user user     1583 Feb 10 13:14 a.txt
-rw-rw-r--.   1 user user     1583 Feb 10 13:14 b.txt
drwxr-xr-x.   2 user user     4096 Nov 22  2013 dir1
drwxr-xr-x.   2 user user     4096 Nov 22  2013 dir2


>$ find . -not -executable 

Won't return any directories, just a list of non-executable files (-type f). And, as it was told, cp copies each and every one of them, individually (since only directories can be copied recursively) to /run/media/user/32GB/prog/

A potential solution is to copy everything first, then do a find/rm

>$ cp -ruv . /run/media/user/32GB/prog/
>$ find /run/media/user/32GB/prog -executable -type f -exec rm {} \;

Or a nasty rsync (I love rsync):

>$ find . -type f -not -executable > /tmp/filelist
>$ rsync -r --include-from=/tmp/filelist . /run/media/user/32GB/prog/

rsync will copy the current directory recursively, adding only the files specified - the non-exec ones. That will prevent the extra write/delete.

  • This is not fun. What I am trying to do is recursively copy all non-executable files. How do I do this? The executables do not have an extension. – user341814 Jul 10 '14 at 2:24
  • Copy, then use find to remove the executable files. I added it in my solution. – Chris Jul 10 '14 at 2:27
  • I did consider this, but it seems...silly to go through the unnecessary copying, removing. – user341814 Jul 10 '14 at 2:29
  • I added another way, using rsync, which will skip the copy/remove – Chris Jul 10 '14 at 2:32
  • rsync is an absolute dream for backup. Use -a for archiving - making exact copies. – Chris Jul 10 '14 at 2:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.