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 제한이 적용됩니다.