查找命令 - 参数列表太长

查找命令 - 参数列表太长

Oracle Linux 5.10
BASH shell

[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

shell 正在执行 /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 

引号可以防止 shell 扩展通配符,然后 find 可以将其用作正则表达式。如果您需要搜索大量符合特定条件的文件(例如“*.foo”),它也会有所帮助。

答案2

最大命令行长度是总大小(以字节为单位),而不是参数的数量。具有以下形式名称的 40k 文件/imr_report_repo/*意味着至少约 800kB,可能更多。这已经超过极限了。

显而易见的解决方案是find为您进行递归。从深度 1 到深度 1,而不是从深度 0 到深度 0。

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) - 请注意尾随/

另请注意,这还受到 128Kbytes 的 ARG_MAX 限制。

相关内容