再帰的にバックアップするとディレクトリがコピーされるわけではない

再帰的にバックアップするとディレクトリがコピーされるわけではない

バックアップするスクリプトに次の行がありますが、すべてのディレクトリを再帰的にコピーするのではなく、ファイルを取得してそれらをまとめて保存するだけです。何が問題なのか、誰か教えてもらえますか?

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

答え1

find の引数-execは、返された各項目に対してそのコマンドを実行するだけです。たとえば、次のようにディレクトリが設定されている場合:

>$ find .
.
./a.txt
./b.txt
./dir1
./dir1/c.txt 
./dir2
./dir2/d.txt

この-exec部分は各行ごとに 1 回実行され、 のテキストが置き換えられます{}。したがって、この場合は、各エントリが指定されたディレクトリに再帰的にコピーされます。

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 は現在のディレクトリを再帰的にコピーし、指定されたファイル (非実行ファイル) のみを追加します。これにより、余分な書き込み/削除が防止されます。

関連情報