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에서 보고한 크기 차이는 다른 원인으로 인한 것이라고 생각됩니다.

여기에 이유가 무엇입니까?

시스템 메시지:

  • 데비안 안정 버전
  • 찾기(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 시스템의 한 가지 해결책은 파일 입력 목록을 사용하여 옵션을 du사용하는 것입니다 --files0-from. 당신의 예를 들어보세요:

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

첫 번째 명령은 모든 파일을 나열하고 이를 \0NUL( )로 구분하여 표준 출력으로 출력합니다. 그런 다음 du표준 입력(파일 이름)에서 해당 목록을 "수집" -하고 du총계를 합산합니다.

관련 정보