web-dev-qa-db-ja.com

Linuxでtmpフォルダを安全にクリーンアップする方法

正確には、tmpfs/tmp、2GBにRAMを使用しています。通常、これで十分ですが、プロセスがファイルを作成し、その後のクリーンアップに失敗することがあります。これは、クラッシュした場合に発生する可能性があります。これらの孤立したtmpファイルを削除する必要があります。そうしないと、将来のプロセスで/ tmpのスペースが不足します。

/ tmpのガベージコレクションを安全に行うにはどうすればよいですか?一部の人々は最終変更のタイムスタンプをチェックすることでそれを行いますが、これらのファイルを必要とする長時間実行プロセスが存在する可能性があるため、このアプローチは安全ではありません。より安全な方法は、最終変更のタイムスタンプ条件を、プロセスがファイルのファイルハンドルを持たないという条件と組み合わせることです。このアプローチまたは他の安全なアプローチを具体化するプログラム/スクリプトなどはありますか?

ちなみに、Linux/Unixでは、クラッシュが発生した場合でも、作成プロセスが終了すると作成されたファイルが削除される、ファイル作成モードでファイルを開くことができますか?

15
Syncopated

あなたはそのようなことを試してみたいかもしれません:

find /tmp -mtime +7 -and -not -exec fuser -s {} ';' -and -exec echo {} ';'

findは、特定の基準に一致するファイルを見つけるために使用されます。

  • -mtime +7は、7日より古いファイルのみを選択します(他の値を使用できます)
  • -exec fuser -s {} ';'は、古い基準に一致するすべてのファイルに対してサイレントモードでフューザーを呼び出します。 fuserは、現在アクセスされているすべてのファイルに対して0(= true)を返し、アクセスされていないファイルに対して1(= false)を返します。アクセスされていないものだけに関心があるため、この-notの前に-execを置きます
  • -exec echo {} ';'は、条件に一致するすべてのファイル名を出力するだけです。ここでは代わりに-exec rm {} ';'を使用することもできますが、これにより一部の使用中のファイルが削除される可能性があるため、最初に単純なエコーを実行する方が安全だと思います。
  • edit:-name 'foo*.bar'-uid 123などを追加して、クリーンアップの影響を特定のファイルパターンに制限したり、偶発的な影響を回避するためのユーザーID。

最後のポイントまで:一度だけ(たとえば、システムのブート時に)書き込まれ、頻繁に読み取られる(たとえば、任意のX-session-cookie)ファイルがある可能性があることを考慮してください。したがって、問題のあるプログラムによって作成されたファイルにのみ影響を与えるために、名前のチェックを追加することをお勧めします。

edit2:最後の質問へ:開いているハンドルがプロセスにない限り、ファイルはディスクから削除されません(少なくともネイティブLinuxファイルシステムの場合) )。問題は、ディレクトリエントリがすぐに削除されることです。つまり、ファイルを削除した時点から、新しいプロセスはファイルを開くことができなくなります(ファイル名が添付されていないため)。

詳細については、次を参照してください: https://stackoverflow.com/questions/3181641/how-can-i-delete-a-file-upon-its-close-in-c-on-linux

edit3:しかし、プロセス全体を自動化したい場合はどうなりますか?

すでに述べたように、一度書き込まれ、たまに読み込まれるファイルがある場合があります(XセッションCookie、PIDファイルなど)。これらは、この小さな削除スクリプトによって除外されません(ファイルを実際に削除する前に、最初にechoを使用してテスト実行したいのはこのためです)。

安全なソリューションを実装する1つの方法は、atimeを使用することです。
atimeは、各ファイルが最後にアクセスされた時刻を格納します。ただし、このファイルシステムオプションは、パフォーマンスにかなりの影響を与えるため、しばしば無効になります( このブログ の20〜30%の領域のどこかによる)。 relatimeはありますが、mtimeが変更された場合にのみアクセス時間を書き込むので、これは役に立ちません。

atimeを使用する場合は、/tmpを別のパーティション(理想的にはramdisk)に配置して、システム全体のパフォーマンスへの影響が大きくなりすぎないようにすることをお勧めします。

atimeを有効にしたら、上記のコマンドラインの-mtimeパラメータを-atimeに置き換えるだけです。
-not -exec fuser -s {} ';'は削除できる可能性がありますが、念のために残しておきます(アプリケーションが長期間ファイルを開いたままにする場合に備えて)。

しかし、システムで必要なものを削除する前に、echoを使用してコマンドをテストすることを忘れないでください!

15
mreithub

自分で転がしてはいけません。

Debian/Ubuntuにはtmpreaperがあり、おそらく他のディストリビューションでも利用可能です。

# tmpreaper - cleans up files in directories based on their age

Sudo apt-get install tmpreaper

cat /etc/tmpreaper.conf 
4
Gringo Suave

あなたの質問の最後の部分について:

「この場合は削除する」というオープン/作成モードは存在しないと思いますが、プロセスは、ファイルのハンドルを開いたままにしておけば、ファイルを作成した直後に安全に削除できます。その後、カーネルはファイルをディスク上に保持し、ファイルを開いた最後のプロセスが(クラッシュまたは通常のいずれかで)終了するとすぐに、ファイルによって占有されていたスペースが解放されます。

一部のプロセスが/ tmpをクリーンアップしないことがあるという問題の一般的な方法として、たとえば here または here のように、マウントの名前空間を確認することをお勧めします。問題のプロセスがシステムデーモンである場合、プライベートな/ tmpファイルシステムを許可する systemd とそのネイティブ機能が興味深いかもしれません。

2
Claudius

上記に同意しますが、追加しますが、常にlsof +L1 | grep tmpそして、「削除された」tmpファイルを保持しているプロセスをkillまたは再起動します。

# lsof +L1 | grep tmp
xfce4-ter  1699  user   32u   REG    8,6      192     0 818552 /tmp/vte966VLX (deleted)
chrome     3301  user  138u   REG    8,6    16400     0 818547 /tmp/etilqs_Z0guKD7p6ork9iG (deleted)
0
SeaPhor

gUIの場合は、これを試してください。 http://bleachbit.sourceforge.net/

きれいにし、スクラブ。プレビューモード。

0
wuxmedia

rm -rf /tmp/*そして、何も壊れないことを願っています...

0
Solomon Ucko

Soより古いファイルのリストを取得し、そのリストから開いているファイルを除外します。

find /tmp -mtime +7 |\
    egrep -v "`lsof -n +D /tmp | awk 'NR>1 {print $9}'| tr \\n \|`" 

lsof -n +D /tmp:/ tmpで開いているファイルを探します
awk 'NR>1 {print $9}':ヘッダーを除いて、lsof出力の9番目の列のみを出力します
tr \\n \|:改行をバーで置き換える(またはegrepではOR)
egrep -v "foo|moo|bar":foo、moo、またはbarを含まない行を出力します