バックアップするスクリプトに次の行がありますが、すべてのディレクトリを再帰的にコピーするのではなく、ファイルを取得してそれらをまとめて保存するだけです。何が問題なのか、誰か教えてもらえますか?
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 は現在のディレクトリを再帰的にコピーし、指定されたファイル (非実行ファイル) のみを追加します。これにより、余分な書き込み/削除が防止されます。