У меня есть следующая строка в скрипте для резервного копирования, и он не копирует рекурсивно все каталоги, он получает файлы, но просто объединяет их все вместе. Может кто-нибудь сказать мне, что с ним не так?
find . -type f -not -executable -exec cp -ruv {} /run/media/user/32GB/prog/ \;
решение1
Аргумент -exec
find просто выполняет эту команду для каждого возвращенного элемента. Так, например, если у вас есть каталог, установленный следующим образом:
>$ find .
.
./a.txt
./b.txt
./dir1
./dir1/c.txt
./dir2
./dir2/d.txt
Часть -exec
будет запущена один раз для каждой строки, заменяя текст на {}
. Таким образом, в вашем случае она рекурсивно скопирует каждую запись в указанный каталог.
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
Кстати, вы также отмечаете -not -executable
. Это имеет реальное значение. Каталоги в Linux являются исполняемыми. (Бит выполнения для каталогов управляет разрешениями на вывод списка содержимого каталога, поскольку папки не могут быть выполнены.)
>$ 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
a.txt
b.txt
dir1/c.txt
dir2/d.txt
Не возвращает никаких каталогов, только список неисполняемых файлов ( -type f
). И, как было сказано, cp
копирует каждый из них по отдельности (так как рекурсивно можно копировать только каталоги) в/run/media/user/32GB/prog/
Потенциальное решение — сначала все скопировать, а затем сделать find
/rm
>$ cp -ruv . /run/media/user/32GB/prog/
>$ find /run/media/user/32GB/prog -executable -type f -exec rm {} \;
Или отвратительное rsync
(я люблю rsync
):
>$ find . -type f -not -executable > /tmp/filelist
>$ rsync -r --include-from=/tmp/filelist . /run/media/user/32GB/prog/
rsync рекурсивно скопирует текущий каталог, добавив только указанные файлы - неexec. Это предотвратит лишнюю запись/удаление.