찾기 명령 - 매개변수 목록이 너무 깁니다.

찾기 명령 - 매개변수 목록이 너무 깁니다.

Oracle Linux 5.10
BASH 셸

[oracle@src01]$ getconf ARG_MAX
131072

[oracle@srv01]$ ls -1 | wc -l
40496

#!/bin/bash
#
# delete files in /imr_report_repo that are older than 15-days
find /imr_report_repo/* -maxdepth 0 -type f -mtime +15 |
while read file
do
    rm -f $file 
done

/usr/bin/find: Argument list too long

올바르게 읽어보면 허용되는 최대 매개변수는 131,072이고 이 디렉터리에는 40,496개의 파일만 있습니다. 확인해 보지는 않았지만 아마도 40,000개의 파일(2주 이상 된 파일)을 삭제하려고 하는 것 같습니다.

답변1

나는 이것이 여기에 대답되었다고 생각합니다.

https://arstechnica.com/civis/viewtopic.php?t=1136262

쉘이 /imr_report_repo/*의 파일 확장을 수행 중인데, 이로 인해 문제가 발생합니다. 비슷한 문제가 있었는데 find 명령을 변경하여 해결했습니다.

find /imr_report_repo/* -maxdepth 0 -type f -mtime +15 

도착하다

find /imr_report_repo/ -name "*" -maxdepth 0 -type f -mtime +15 

따옴표는 쉘이 와일드카드 문자를 확장하는 것을 방지합니다. 그러면 find는 정규식으로 사용할 수 있습니다. 특정 기준(예: "*.foo")과 일치하는 많은 수의 파일을 검색해야 하는 경우에도 도움이 될 수 있습니다.

답변2

최대 명령줄 길이는 인수 수가 아닌 총 크기(바이트)입니다. 아래 형식의 이름을 가진 40k 파일은 /imr_report_repo/*최소 약 800kB, 아마도 그 이상을 의미합니다. 이것은 한계를 넘어선 것입니다.

확실한 해결책은 find재귀를 수행하는 것입니다. 깊이 0에서 깊이 0이 아닌, 깊이 1에서 깊이 1로.

find /imr_report_repo/ -mindepth 1 -maxdepth 1 -type f -mtime +15 -delete

원본 파일과 달리 여기에는 .이름이 (점 파일)로 시작하는 파일이 포함됩니다. 이 작업을 원하지 않으면 제외하세요.

find /imr_report_repo/ -mindepth 1 -maxdepth 1 -name '.*' -prune -o -type f -mtime +15 -delete

대부분의 find구현에는 -maxdepth그런 기능이 있습니다 -delete. 그렇지 않은 경우 결과를 다음으로 파이프하지 마십시오 . 약간 느리고 개행 문자가 포함된 파일 이름이 손상됩니다( 위치를 while read사용한 이후의 백슬래시 및 후행 공백도 포함 ).read사용했어야 했어IFS= read -r). 를 사용하세요 -exec. 그게 바로 그 용도입니다.

find /imr_report_repo/ -mindepth 1 -maxdepth 1 -type f -mtime +15 -exec rm -f {} +

답변3

시도해 보세요: find /imr_report_repo/ -maxdepth 1 -type f -mtime +15 -exec rm {} +또는 @Fiximan이 제안한 대로find /imr_report_repo/ -maxdepth 1 -type f -mtime +15 -delete

/imr_report_repo/(그러나 /imr_report_repo 자체는 아님)의 바로 하위 디렉터리에 있는 파일을 삭제하려는 경우 find /imr_report_repo/*/ -maxdepth 0 -type f -mtime +15 -exec rm {} +(또는 ... -delete)를 사용하세요. - 후행에 주의하세요./

또한 여기에는 128KB의 ARG_MAX 제한이 적용됩니다.

관련 정보