언제 발견될 것인가? -exec COMMAND {} +` COMMAND를 여러 번 실행하시겠습니까?

언제 발견될 것인가? -exec COMMAND {} +` COMMAND를 여러 번 실행하시겠습니까?

만약 내가한다면

find . -exec echo {} +

모든 경로를 한 줄에 인쇄합니다. 즉, 명령은 echo한 번만 실행됩니다.

그러나 man find따르면

-exec command {} +
    ... the number of invocations of the command will 
be much  less  than  the  number  of matched files. ...

어떤 경우에는 명령이 여러 번 실행되는 것 같습니다. 내가 맞나요? 예를 들어주세요.

답변1

POSIX 정의find -exec 유틸리티_이름 [매개변수...] {} +처럼:

주 표현의 끝은 <세미콜론>이나 <더하기 기호>로 구두점을 찍어야 합니다. 두 문자 "{}"만 포함하는 인수 바로 뒤에 있는 <더하기 기호>만 기본 표현식의 끝을 강조합니다. <더하기 기호>의 다른 용도는 특별한 용도로 간주되어서는 안 됩니다. 기본 표현식에 <세미콜론>이 붙은 경우 유틸리티는유틸리티 이름각 경로 이름에 대해 한 번 호출되어야 하며 유틸리티가 종료 상태로 0 값을 반환하는 경우 기본 경로는 true로 평가되어야 합니다. ㅏ유틸리티 이름또는토론두 문자 "{}"만 현재 경로 이름으로 바꿔야 합니다. 만약유틸리티 이름또는토론문자열에 "{}" 두 문자가 포함되어 있는지 여부는 구현에 따라 정의되지만 "{}" 두 문자만 포함되는 것은 아닙니다.찾다이 두 문자를 바꾸거나 변경되지 않은 문자열을 사용하십시오.

기본 표현식이 <더하기 기호>로 구분되는 경우 기본 표현식은 항상 true로 평가되며 기본 표현식이 평가되는 경로 이름은 컬렉션으로 집계됩니다. 실용적인 사항유틸리티 이름 각 집계 경로 이름 집합에 대해 한 번씩 호출되어야 합니다. 각 호출은 컬렉션의 마지막 경로 이름이 집계된 후에 시작되어야 하며찾다유틸리티는 이 기본에 대한 다음 그룹(있는 경우)의 첫 번째 경로 이름을 집계하기 전에 종료되지만 호출이 다른 기본의 평가 전, 도중 또는 후에 발생하는지 여부는 지정되지 않습니다. 호출이 종료 상태로 0이 아닌 값을 반환하는 경우찾다 유틸리티는 0이 아닌 종료 상태를 반환해야 합니다. 두 문자 "{}"만 포함하는 인수는 집계된 경로 이름 집합으로 대체되어야 하며, 각 경로 이름은 집계 순서에 따라 호출 유틸리티에 별도의 인수로 전달됩니다.두 개 이상의 경로 이름 집합의 크기는 유틸리티 실행으로 인해 시스템의 {ARG_MAX} 제한이 초과되지 않도록 제한되어야 합니다.. 두 문자 "{}"를 포함하는 인수가 여러 개 있는 경우 동작은 지정되지 않습니다.

찾은 파일 이름의 길이가 시스템 설정을 초과하는 경우 ARG_MAX이 명령이 실행됩니다 .

당신이 ARG_MAX사용할 수있는구성 파일 가져오기:

$ getconf ARG_MAX
2097152

일부 시스템에서는 실제 값이 ARG_MAX다를 수 있습니다.여기자세한 내용은.

답변2

POSIX 시스템에서 새 프로세스의 매개변수 목록에는 최대 길이가 있습니다. find파일 경로가 이보다 길면 실행이 분할됩니다. Linux의 제한 사항을 보려면 다음을 사용하세요. xargs --show-limits(Mac OS에서는 사용할 수 없습니다. 더 나은 대안을 아는 사람이 있으면 여기에 의견을 남겨주세요.)

편집하다:Gnouc의 답변에서 직접 훔쳐서 매개변수 목록의 최대 길이를 얻는 POSIX 방법은 getconf ARG_MAX. 하지만 내 Mac OS 컴퓨터에서 실험을 실행했는데 find이 숫자의 절반 이상이 사용된 것 같습니다 . 이는 작동하는 시스템에서 xargs --show-limits최대 인수 길이를 사용하지 않을 것이라고 들었지만(이 경우 해당 숫자의 약 절반을 사용함) 그에 대한 설명을 찾을 수 없다는 사실과 일치합니다. 이유.

편집 2:find각 호출에서 몇 개의 인수가 함께 붙어 있는지 확인하는 신뢰할 수 있는 유일한 방법은 다음을 실행하여 실험하는 것 같습니다 .

find / -exec echo {} + | wc -cl

각 호출마다 find한 줄의 출력이 있으므로 echo를 사용하여 계산할 수 있습니다 wc -l. ed의 총 바이트 수 echo는 반대 출력입니다 wc -c. 하나씩 나누면 명령 호출당 인수의 평균 바이트 수를 얻을 수 있습니다(반올림으로 인해 약간 낮기는 하지만 시스템 평균 경로 길이의 약 절반입니다).

관련 정보