このエントリーをはてなブックマークに追加

概要

 Linuxサーバを長い間運用していると、徐々にディスクの空き領域が減っていって、 気が付いたらログ用ボリュームの使用率が100%になっていた、というような経験は誰でも1度はあるかと思います。 そんな時、サイズの大きいファイルを見つけて削除することで対策することが多いと思いますので、 Linux標準の find コマンドを使用して指定したサイズ以上のファイルを見つける方法、またそれを削除する方法を紹介します。

構成

サーバ構成

OSバージョン

CentOS 7.5.1804 x86_64

ソフトウェア・パッケージ一覧

  • findutils-4.5.11-5.el7.x86_64.rpm

手順

検索対象ディレクトリを絶対パスで指定し、指定したサイズ以上のファイルをfindコマンドで検索する

 検索対象のディレクトリを絶対パス(今回の例は/data/ansible/)で指定し、検索条件を「1KB以上のファイル」とし、 検索にヒットしたファイルを一覧で表示します。 検索対象ディレクトリを絶対パスで指定した場合は、検索結果も絶対パスで表示されます。 この例では /data/ansible/ ディレクトリ以下の1KB以上のファイルを検索して表示していますが、 ファイルサイズがいくつかは表示されていません。

$ find /data/ansible/ -type f -size +1k
/data/ansible/test/inventory/id_rsa
/data/ansible/test/postgresql10_playbook.yml
/data/ansible/test/files/postgresql.conf
/data/ansible/test/files/pg_hba.conf
/data/ansible/test/files/postgresql-10.service
/data/ansible/test/files/pg_hba.conf.bk20181227
/data/ansible/test/files/postgresql-10.service.bk20181227
/data/ansible/test/files/postgresql.conf.bk20181227
/data/ansible/test/files/httpd.conf.bk20190103
/data/ansible/test/files/httpd.conf
/data/ansible/test/test_playbook.yml.bk20181227
/data/ansible/test/test_playbook.yml.bk20181228
/data/ansible/test2/common/README.md
/data/ansible/test2/common/meta/main.yml

findコマンドの検索結果を詳細に表示する

 上の例ではディレクトリパス+ファイル名しか表示されないため、 ファイルサイズやパーミッションなどは分かりません。 find コマンドに -ls オプションを指定することで検索にヒットしたファイルを詳細情報付きの一覧で表示することができます。 詳細情報付きというのは、 ls -dils を実行した時と同じ情報が表示されます。

$ find /data/ansible/ -type f -size +1k -ls
12732514    4 -rw----r--   1 centos   centos       1692 Jun  3  2017 /data/ansible/test/inventory/id_rsa
12732531    4 -rw-rw-r--   1 ansible  ansible      2507 Jan  1 16:38 /data/ansible/test/postgresql10_playbook.yml
12732530   24 -rw-------   1 ansible  ansible     22743 Dec 26 15:20 /data/ansible/test/files/postgresql.conf
12732529    8 -rw-------   1 ansible  ansible      4635 Dec 26 15:22 /data/ansible/test/files/pg_hba.conf
12732532    4 -rw-r--r--   1 ansible  ansible      1719 Dec 26 15:25 /data/ansible/test/files/postgresql-10.service
12732528    8 -rw-------   1 ansible  ansible      4513 Dec 26 14:46 /data/ansible/test/files/pg_hba.conf.bk20181227
12732524    4 -rw-r--r--   1 ansible  ansible      1728 Dec 26 15:24 /data/ansible/test/files/postgresql-10.service.bk20181227
12732527   24 -rw-------   1 ansible  ansible     22721 Dec 26 14:46 /data/ansible/test/files/postgresql.conf.bk20181227
12732517   12 -rw-r--r--   1 ansible  ansible     11738 Jan  1 16:20 /data/ansible/test/files/httpd.conf.bk20190103
12732534   12 -rw-r--r--   1 ansible  ansible     11922 Jan  3 07:35 /data/ansible/test/files/httpd.conf
12732513    4 -rw-rw-r--   1 ansible  ansible      1643 Dec 26 14:43 /data/ansible/test/test_playbook.yml.bk20181227
12732518    4 -rw-rw-r--   1 ansible  ansible      2347 Dec 26 15:58 /data/ansible/test/test_playbook.yml.bk20181228
8430138    4 -rw-rw-r--   1 ansible  ansible      1328 Feb 18 15:51 /data/ansible/test2/common/README.md
8430141    4 -rw-rw-r--   1 ansible  ansible      1973 Feb 18 15:51 /data/ansible/test2/common/meta/main.yml

findコマンドの検索結果を少し詳細に表示する

 上の例では検索結果が ls -dils と同じだけ表示されるため、情報量がやや多すぎるかもしれません。 検索結果を表示する際に ls で表示される量を調整したい(lsのオプションを指定したい)場合は find の -exec オプションを使うことで実現できます。 以下の例では検索結果のファイルを ls -l で表示しています。一般的にはこれぐらいがちょうど良いのかなと思います。

$ find /data/ansible/ -type f -size +1k -exec ls -l {} \;
-rw----r--. 1 centos centos 1692 Jun  3  2017 /data/ansible/test/inventory/id_rsa
-rw-rw-r--. 1 ansible ansible 2507 Jan  1 16:38 /data/ansible/test/postgresql10_playbook.yml
-rw-------. 1 ansible ansible 22743 Dec 26 15:20 /data/ansible/test/files/postgresql.conf
-rw-------. 1 ansible ansible 4635 Dec 26 15:22 /data/ansible/test/files/pg_hba.conf
-rw-r--r--. 1 ansible ansible 1719 Dec 26 15:25 /data/ansible/test/files/postgresql-10.service
-rw-------. 1 ansible ansible 4513 Dec 26 14:46 /data/ansible/test/files/pg_hba.conf.bk20181227
-rw-r--r--. 1 ansible ansible 1728 Dec 26 15:24 /data/ansible/test/files/postgresql-10.service.bk20181227
-rw-------. 1 ansible ansible 22721 Dec 26 14:46 /data/ansible/test/files/postgresql.conf.bk20181227
-rw-r--r--. 1 ansible ansible 11738 Jan  1 16:20 /data/ansible/test/files/httpd.conf.bk20190103
-rw-r--r--. 1 ansible ansible 11922 Jan  3 07:35 /data/ansible/test/files/httpd.conf
-rw-rw-r--. 1 ansible ansible 1643 Dec 26 14:43 /data/ansible/test/test_playbook.yml.bk20181227
-rw-rw-r--. 1 ansible ansible 2347 Dec 26 15:58 /data/ansible/test/test_playbook.yml.bk20181228
-rw-rw-r--. 1 ansible ansible 1328 Feb 18 15:51 /data/ansible/test2/common/README.md
-rw-rw-r--. 1 ansible ansible 1973 Feb 18 15:51 /data/ansible/test2/common/meta/main.yml

findコマンドで検索対象ディレクトリを相対パスで指定する

 ディレクトリ階層が深いと検索結果のパス部分の表示が長くなり、画面の右で折り返されて見づらくなってしまいます。 検索したいディレクトリが絞られている場合は、カレントディレクトリを移してから検索対象ディレクトリを相対パスで指定すると、 検索結果も相対パスで表示されるため見やすくなります。 以下の例では上と同じ /data/ansible/ ディレクトリ以下を検索しますが、 先にカレントディレクトリを /data/ansible/ へ移したうえで、相対パス指定で検索しています。 「ディスクの空きが少なくなってきたのでおっきいファイルを見つけて削除したい!」 といったケースではこの方法がお勧めかなと思います。

$ cd /data/ansible/
$ find ./ -type f -size +1k -exec ls -l {} \;
-rw----r--. 1 centos centos 1692 Jun  3  2017 ./test/inventory/id_rsa
-rw-rw-r--. 1 ansible ansible 2507 Jan  1 16:38 ./test/postgresql10_playbook.yml
-rw-------. 1 ansible ansible 22743 Dec 26 15:20 ./test/files/postgresql.conf
-rw-------. 1 ansible ansible 4635 Dec 26 15:22 ./test/files/pg_hba.conf
-rw-r--r--. 1 ansible ansible 1719 Dec 26 15:25 ./test/files/postgresql-10.service
-rw-------. 1 ansible ansible 4513 Dec 26 14:46 ./test/files/pg_hba.conf.bk20181227
-rw-r--r--. 1 ansible ansible 1728 Dec 26 15:24 ./test/files/postgresql-10.service.bk20181227
-rw-------. 1 ansible ansible 22721 Dec 26 14:46 ./test/files/postgresql.conf.bk20181227
-rw-r--r--. 1 ansible ansible 11738 Jan  1 16:20 ./test/files/httpd.conf.bk20190103
-rw-r--r--. 1 ansible ansible 11922 Jan  3 07:35 ./test/files/httpd.conf
-rw-rw-r--. 1 ansible ansible 1643 Dec 26 14:43 ./test/test_playbook.yml.bk20181227
-rw-rw-r--. 1 ansible ansible 2347 Dec 26 15:58 ./test/test_playbook.yml.bk20181228
-rw-rw-r--. 1 ansible ansible 1328 Feb 18 15:51 ./test2/common/README.md
-rw-rw-r--. 1 ansible ansible 1973 Feb 18 15:51 ./test2/common/meta/main.yml

findコマンドで検索にヒットしたファイルを削除する

 上の例では検索結果として表示されたファイル名の末尾に .bk年月日 の形式のものが存在していますが、 なんとなく想像できる通りファイルを編集する前にバックアップとして取られたものになります。 サーバを運用していると、なんとなく取られているこれらのバックアップファイルが地味に積み重なって ディスクの空き容量を圧迫する要因になっていたりします。 サイズの大きいバックアップファイルを特定して消したい場合にも find コマンドが使用できます。

 以下の例では、サイズが1KB以上のファイルで、かつファイル名に「.bk」という文字を含むものを表示しています。 単純に上の例の実行結果にパイプ(|)でつなげて grep しても良いですが、 find のオプションにファイル名を指定できる -name が存在しているため、これを使用します。 -name オプションではワイルドカード(*)が指定できます。 grepの場合と違ってワイルドカードを指定しないと、「.bk」という3文字のファイルを検索してしまいます。

$ cd /data/ansible/
$ find ./ -type f -size +1k -exec ls -l {} \; | grep .bk
-rw-------. 1 ansible ansible 4513 Dec 26 14:46 ./test/files/pg_hba.conf.bk20181227
-rw-r--r--. 1 ansible ansible 1728 Dec 26 15:24 ./test/files/postgresql-10.service.bk20181227
-rw-------. 1 ansible ansible 22721 Dec 26 14:46 ./test/files/postgresql.conf.bk20181227
-rw-r--r--. 1 ansible ansible 11738 Jan  1 16:20 ./test/files/httpd.conf.bk20190103
-rw-rw-r--. 1 ansible ansible 1643 Dec 26 14:43 ./test/test_playbook.yml.bk20181227
-rw-rw-r--. 1 ansible ansible 2347 Dec 26 15:58 ./test/test_playbook.yml.bk20181228
$ find ./  -type f -size +1k -name *.bk* -exec ls -l {} \;
-rw-------. 1 ansible ansible 4513 Dec 26 14:46 ./test/files/pg_hba.conf.bk20181227
-rw-r--r--. 1 ansible ansible 1728 Dec 26 15:24 ./test/files/postgresql-10.service.bk20181227
-rw-------. 1 ansible ansible 22721 Dec 26 14:46 ./test/files/postgresql.conf.bk20181227
-rw-r--r--. 1 ansible ansible 11738 Jan  1 16:20 ./test/files/httpd.conf.bk20190103
-rw-rw-r--. 1 ansible ansible 1643 Dec 26 14:43 ./test/test_playbook.yml.bk20181227
-rw-rw-r--. 1 ansible ansible 2347 Dec 26 15:58 ./test/test_playbook.yml.bk20181228

 上でファイル名に .bk を含むバックアップファイルの一覧が表示されましたが、 確かに消してよいファイルであることが確認できたら、続けて削除してしまいます。 find コマンドの -exec オプションで ls -l を指定していましたが、これを rm -f に変更して実行します。

$ find ./ -type f -size +1k -name *.bk* -exec rm -f {} \;

 再度1KB以上のファイルを表示すると、ファイル名に .bk 含むファイルが削除されていることが分かります。 今回の例ではファイル名に .bk を含むファイルのサイズが全て1KB以上だったのでバックアップファイルが全部消えています。 (例としてはあまり面白くなかったですね。。。)

$ find ./ -type f -size +1k -exec ls -l {} \;
-rw----r--. 1 ansible ansible 1692 Jun  3  2017 ./test/inventory/id_rsa
-rw-rw-r--. 1 ansible ansible 2507 Jan  1 16:38 ./test/postgresql10_playbook.yml
-rw-------. 1 ansible ansible 22743 Dec 26 15:20 ./test/files/postgresql.conf
-rw-------. 1 ansible ansible 4635 Dec 26 15:22 ./test/files/pg_hba.conf
-rw-r--r--. 1 ansible ansible 1719 Dec 26 15:25 ./test/files/postgresql-10.service
-rw-r--r--. 1 ansible ansible 11922 Jan  3 07:35 ./test/files/httpd.conf
-rw-rw-r--. 1 ansible ansible 1328 Feb 18 15:51 ./test2/common/README.md
-rw-rw-r--. 1 ansible ansible 1973 Feb 18 15:51 ./test2/common/meta/main.yml

 find コマンドでファイルを検索して削除するときは、オプションを間違えると事故につながる危険性があります。 先に検索結果を ls で表示してから rm で消すことと、検索・削除対象ディレクトリの指定は相対パスで指定するように心がけてください。

 また、今回の例ではファイルサイズ1KBを検索条件として指定しましたが、MBやGBを条件としたい場合は、 -size オプションで以下の通り単位を指定してください。

■-sizeで指定可能な単位
単位説明
b512バイトブロック
cバイト
w2バイト文字
kキロバイト(1,024バイト)
Mメガバイト(1,048,576バイト)
Gギガバイト(1,073,741,824バイト)