検索コマンド - パラメータリストが長すぎます。

検索コマンド - パラメータリストが長すぎます。

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は正規表現として使用できます。特定の基準に一致する多数のファイルを検索する必要がある場合にも役立ちます。

答え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制限が適用されます。

関連情報