find -exec duの要約が異なるのはなぜですか?

find -exec duの要約が異なるのはなぜですか?

/media/data/Selbstgemachtフォルダに家族の写真と映画があり、すべての写真のサイズを知りたいです。 /media/dataで私はfind Selbstgemacht -type f -iname '*.jpg' -exec du -ch '{}' +それを使用して5,1GBを返します。
ところで、「Selbstgemacht」フォルダに入って使用すると、find . -type f -iname '*.jpg' -exec du -ch '{}' +7.0GBが出ます。

次に、findの出力を比較して、同じファイルが見つかったことを確認します。親
フォルダからサブフォルダfind Selbstgemacht -type f -iname '*.jpg' -printf '%P\n' |sort > test1.txt
find . -type f -iname '*.jpg' -printf '%P\n' |sort > ../test2.txt

ファイルは同じなので、両方の find コマンドはまったく同じファイルを探します。したがって、duが報告したサイズの違いは、他の原因によるものと考えられます。

ここで理由は何ですか?

システムメッセージ:

  • Debian 安定版
  • 検索(GNU findutils)4.4.2
    • D_TYPE O_NOFOLLOW(有効化)
    • LEAF_OPTIMISATION、FTS()、CBO(レベル= 0)
  • du(GNU coreutils) 8.13

答え1

find ... -exec cmd {} +cmdコマンドに渡される引数のサイズ制限に違反しないように、必要な回数だけ実行されます。

使用時find . -exec du {} +のファイルリストのサイズが使用時よりも小さくなりますfind verylongdirname -exec du {} +

したがって、このコマンドよりも多くのコマンドfind verylongdirnameが実行される可能性が高くなります。最後に表示される合計は、すべてのファイルを除く最後の実行の合計です(より多くのものです)。dufind .du以前は確認のためにコマンドをパイプできましたgrep 'total$'

答え2

あなたが見なければならないのは、どちらの場合もイメージのディスクスペース使用量を取得できないことです。何千もの画像がある場合、どちらの場合もexec呼び出し制限を超える可能性があります。

なぜ?このコマンドはシステムコール-exec (...) +にパラメータを追加します。execvpマニュアルページでは、基本的なシステムコールの制限を次のように定義します。マニュアルページの実行):

Limits on size of arguments and environment
   Most UNIX implementations impose some limit on the total  size  of  the
   command-line argument (argv) and environment (envp) strings that may be
   passed to a new program. (...)

   On  kernel  2.6.23  and  later, most architectures support a size limit
   derived from the soft RLIMIT_STACK resource  limit  (see  getrlimit(2))
   that is in force at the time of the execve() call.  (...)   This change
   allows programs to have a much larger argument and/or environment list.
   For these  architectures,  the  total  size  is  limited  to 1/4 of the
   allowed stack size. (...) Since Linux 2.6.25, the kernel places a floor
   of 32 pages on this size limit, so that, even when RLIMIT_STACK is  set
   very low, applications are guaranteed to have at least as much argument
   and environment space as was provided by Linux 2.6.23 and earlier (This
   guarantee  was not provided in Linux 2.6.23 and 2.6.24.)  Additionally,
   the limit per string is 32 pages (the kernel constant  MAX_ARG_STRLEN),
   and the maximum number of strings is 0x7FFFFFFF.

したがって、ファイルのリストが非常に長い場合、システムの制限にすばやく到達します。また、相対パスが長いと、より多くのメモリが使用されるため、制限に早く到達するため、両方のコマンドの結果が異なります。

解決策がある

GNUシステムの1つの解決策は、ファイル入力リストを使用してオプションをdu使用することです--files0-from。あなたの例を見てください:

find Selbstgemacht -type f -iname '*.jpg' -print0 | du --files0-from=- -ch

最初のコマンドはすべてのファイルをリストし、それを\0NUL()で区切って標準出力に出力します。次に、du標準入力(ファイル名)でそのリストを「収集」し-du合計を合計します。

関連情報