echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

【Linux】lsコマンドで「引数が多すぎます」となった場合の対処方法

'ls'コマンドは、Linuxでも非常によく使うコマンドの一つだと思いますが、例えば

> ls -l /mnt/c/users/makky12/*.*

みたいにワイルドカード指定で実行した時に、一致するファイルが多すぎると*1「引数が長すぎます」というエラーが発生してしまいます。

こんな時、どういう回避策があるか、という話です。

ワイルドカードを指定しない

> ls -l /mnt/c/users/makky12/

上記のように、ワイルドカードを指定しなければ「引数が長すぎます」エラーは発生しません。(ここで記載した通り、ワイルドカード指定すると、一致したファイルすべてを引数にしてしまうため)

ただし、当然ワイルドカードでの指定ができないため、その後に

といったことが必要になります。(てか、ただでさえ一致するファイルが膨大なのに、もし条件に一致しないファイルのほうがはるかに多い場合、かなり処理に時間がかかってしまう気がします。)

■findコマンドを使う

> find /mnt/c/users/makky12/ -name "*.*" -type f

というように、findコマンドの-nameオプションを指定すれば、やはり「引数が長すぎます」エラーを発生させず、ファイルの一覧を表示させることができます。

※ちなみに、例えば「'ls'コマンドの'-l'オプションを付けた場合と同じ結果を得たい」とかなら、

> find /mnt/c/users/makky12/ -name "*.*" -type f -exec ls -l {} \;

としたり、あるいは'xargs'を使用して、

> find /mnt/c/users/makky12/ -name "*.*" -type f | xargs ls -l

とするやりかたもあります。

ただ、長い(=たくさんの)処理を実行させるには、ちょっと不向きかも。

そして、このやり方だと、別の問題が…


サブディレクトリは対象にしたくない!

'find'コマンドは、条件に一致すれば、サブディレクトリのファイルも取得します。
それで問題ないならいいんですが、場合によっては「サブディレクトリは対象外にしたい」ということもあると思います。(てか、僕がこの問題に直面した時はそうでした)

じゃあどうやるのか…といえば、こんなやり方があります。

■「-maxdepth 1」オプションを付ける

「-maxdepth」オプションを使用すれば「検索する最大の深さ」が指定できます。
これを使用して

> find /mnt/c/users/makky12/ -maxdepth 1 -name "*.*" -type f

とすれば、サブディレクトリは検索対象にしません。
※なお、検索ベースのディレクトリが「/mnt/c/users/makky12/」なので、maxdepthの引数は'1'(=1つ下の階層、つまり「/mnt/c/users/makky12/」ディレクトリ直下まで)とする必要があります。
これが例えば「/mnt/c/users/makky12/*.* 」を指定していた場合、すでに「/mnt/c/users/makky12/」の内部を指定しているため、maxdepthは'0'とする必要があります。

ただ、僕の使用していた環境では、maxdepthが使用できなかったわけでして…

■「grep」コマンドで頑張る

とまあ、結局'grep' コマンド頼みになってしまったわけですが、サブディレクトリ以下のファイルの場合、かならずパスの「/mnt/c/users/makky12/」の後のどこかに'/'があるのを利用して、

> find /mnt/c/users/makky12/ -name "*.*" -type f | grep '^/mnt/c/users/makky12/[^/]*$'

てな感じで、「'/mnt/c/users/makky12/'で始まり、そのあとに'/'を含まない文字列」のみ表示対象とすれば、結果的にサブディレクトリのファイルを除外することができる、というわけです。
(てか、ネットでこのやり方を知ったときは、目からうろこでした。「何かよいコマンドやスクリプトが…」と思っていたのですが、考え方が固いというか、もっと柔軟な考え方ができなければ...と思った次第です。)

以上、僕が業務で直面した「lsコマンドで「引数が多すぎます」となった場合の対処方法」でした。

…まあ、'maxdepth'が使えれば問題なかったんですけどね。

てか、本番稼働のサーバー(しかもAPサーバー(ファイルサーバじゃない))の1つのディレクトリに15万以上もファイルを置くって、運用上どうなのよ、それ?

*1:正確には「一致したファイル名の総バイト数が「ARG_MAX」より大きい」場合に発生します。