技術研究所のまつけんです。

 

技術研究所(技研)では、画像処理や機械学習のプロジェクトを幾つか進めています。それらの処理をするために、サーバ (ゲーミング・デスクトップPC + Ubuntu Linux) を2台ほど運用しているのですが、今般、その /home が溢れてしまいました。こんな感じです:

# df | grep /home
/dev/sdb1      2883220084 2883220084          0 100% /home

昨日の夕方から130 GBも増えていたので、何事かと調べたところ、各自の ~/.local/share/Trash/files/ が凄い容量になっていました。調べてみたところ、Jupyter Notebook 上で GUI で削除したファイルは削除されるのではなく、全てこちらの ‘Trash’ に移動されるようです。

というわけで今回は、各自の Trash を整理した話と、再発防止策として、各自の Trash を定期的に削除するようにしたことについて書きたいと思います。UNIX/Linux システムで /home (に限らず、他のストレージについても) が溢れた場合の調査法や対処法について知りたい方は参考にしてください。

原因調査

まず、どのディレクトリが原因なのか調べます。UNIX/Linux において、ストレージの使用量を調べるコマンドとして、df と du があります。前者は「disk-free」、後者は「disk usage」の略です。前者はストレージ全体の、後者はディレクトリ毎の使用量を調べることが出来ます。誰の、どの、ディレクトリの容量が大きいのか調べたいので du を使います。

ただし、一般的な使い方をしているPCで

# cd /home
# du

とやってしまうと、何万行もの結果が表示されてしまいます。そこで、「-d 1」を付けて表示する「深さ」を1段に制限します。また、デフォルトではKB単位での表示になるので、「-h」を付けて「人間が読みやすい」表示にするのが良いでしょう。

# cd /home
# du -d 1 -h
12M ./testuser
4.4G ./matsken
789G ./yamada
(略)

この例ではyamadaさんが目立って大きいので、そこを調べます:

# du -d 1 -h yamada/
678G ./.local
(略)

さらに、「.local」が大きいので「du -d 1 -h yamada/.local/」を調べると、「du -d 1 -h yamada/.local/Trash/」が大きいことがわかりました。さらに、その中を調べてみたところ、Jupyter Notebook のファイル (.ipynb) や、実験で作成した画像ファイル (.JPG や .PNG) が大量に入っていることがわかりました。Jupyter 上でファイルやディレクトリの左にあるチェックボックスをONにして、ゴミ箱ボタン:

を押すと削除されるのではなく、~/.local/share/Trash/files/ に移動されるということがわかりました。Jupyter から、Trash の使用状況を調べたり、削除したりすることも可能です:

が、利用者全員に定期的に実施してくれるように頼み、それに頼るのは、あまり現実出来ではありません。少し話はそれますが、私の場合、ときどき使うようなものは、___TMP___.ipynbというファイルにまとめて入れています。また、 

# ゴミ箱を空にする
!rm -rf ~/.local/share/Trash/
!mkdir -p ~/.local/share/Trash/

は、Trashをディレクトリごと削除し、作り直す内容となっています。つまり、

# ゴミ箱を空にする
!rm -rf ~/.local/share/Trash/*

でも同じことなのですが、rm -rf とを一緒に使うのは危険なので、そのようにしていません。誤って、~/.local/share/Trash/ と の間にスペースを入れてしまい、それに気付かずに実行してしまうと、カレントディレクトリ内の全てのアイテムが消えてしまうからです。

さて、話を元に戻しましょう。今回の恒久対策として、全員の Trash を削除するシェルスクリプト:

LOG=/home/clean_trash_of_each_user.log
( echo -n "Started : " ; date +%Y-%m-%d_%H-%M-%S ) >> $LOG
for USER_NAME in `find /home -maxdepth 1 -type d`
do
DIR="$USER_NAME/.local/share/Trash/"
if [ -e "$DIR" ]
then
echo "$DIR" >> $LOG
#du -d 0 -h "$DIR" >> $LOG
rm -rf "$DIR"
fi
done
( echo -n "Finished: " ; date +%Y-%m-%d_%H-%M-%S ) >> $LOG

を作成し、cronで毎週月曜日の早朝 (4時) に実行するようにしました。具体的には、以下のようにcronを設定します:

# m h dom mon dow command
0 4 * * 1 /home/clean_trash_of_each_user.sh

スクリプト開始時と終了時、Trash 削除時にログを出力するようにしているので、いつ、誰の Trash を削除したのか記録が残ります:

Started : 2020-06-01_04-00-01
/home/yamada/.local/share/Trash/
Finished: 2020-06-01_04-00-02

如何でしたか? 普段、UNIX/Linux をコマンドラインで使っていると、rm コマンドで即座に消すことが多く、Trash は使わないので盲点でしたが、無事に原因究明と恒久対策ができました。また、何人かで利用している場合、利用者の中に GUI で Trash を利用する人も居るかも知れません。そういった場合に、この記事がお役に立てばと思います。