cat / dev / null> file.logはDarwinの大きなファイルを切り捨てません


15

過去に、Linuxシステムでは、を使用して、大きく開いたログファイル(つまり、プロセスによってアクティブに書き込まれているファイル)を切り捨てることができましたcat /dev/null > file.log

ただし、10.9(Mavericks)では、そうではないようです。アプリケーションによって記録されている11GBのファイルがありますが、そのファイルで同じコマンドを実行しても何も起こらないようです。

些細なサイズのファイルでこれを試しても、うまくいきます。

ここにありls -l /dev/nullます:

crw-rw-rw- 1 root wheel 3, 2 Dec 16 12:49 /dev/null

私もcp /dev/null file.log役に立たないようにしました。

切り捨て機能(man 2 truncateダーウィン)を利用するかもしれないと考えて、これをコンパイルし、サイズが小さいファイルと実際のログファイルの2つのファイルに対して実行しました。繰り返しますが、それは些細なファイルに対して機能し、はるかに大きなログでは機能しませんでした。

/*
 * Copyright (c) 2013 Thomas de Grivel <thomas@lowh.net>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 ...
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <unistd.h>

int main (int argc, const char **argv)
{
        int e = 0;
        while (--argc) {
                argv++;
                if (truncate(*argv, 0)) {
                        e = 4;
                        warn("%s", *argv);
                }
        }
        return e;
}

プロセスは0、使用するファイルに関係なく戻ります。


どうしてうまくいかなかったのですか?何をしないdudu -hと言いますか?ファイルがスパースファイルである可能性はありますか?
ミケル

2
また、この投稿にライセンスを含める目的は何ですか?ノイズを追加するだけのようです。
ミケル

du -h /tmp/file.log結果11G /tmp/file.log
13

@Mikel礼儀としてライセンスを含めました...ほとんどを編集したことに気付くでしょう。
chb

1
ライセンスは、ここでの本当の逸品答え気晴らしです
iruvar

回答:


12

cat /dev/null出力を生成しないコマンドを記述する方法が少し複雑です。:またはtrueより明白なものです。

すべてではcat /dev/null > file: > fileとさえ> fileほとんどのシェルでは、シェルは、その後何も出力しないアプリケーションを実行し、標準出力にO_TRUNCでファイルを開き、そのファイルは閉じられ、切り捨てられたまま。

ただし、その場合、またはtruncateシステムコールを使用しているときに、そのファイルがいっぱいになっているプロセスがO_APPENDフラグでファイルを開かなかった場合、次にファイル上で開いているファイル記述子に書き込むときに、書き込みますファイル内にあったオフセットのデータ。

HFS +はスパースファイルをサポートしていないため、そのオフセットの前のスペースはシステムによって再割り当てされ、ゼロで埋められる必要があります。

そのため、切り捨てる前に、そのファイルに書き込んでいるアプリケーションを強制終了する必要があります。または、アプリケーションでファイルを開くことを確認する必要がありますO_APPEND>>シェルリダイレクトを使用する場合など)。

試してみたい場合:

$ exec 3> x
$ yes | head -n 50000 >&3
$ ls -ls x
200 -rw-r--r--  1 me me  100000 Dec 16 21:32 x

シェルのfd 3はファイル内で100000バイトです

$ : > x
$ ls -ls x
0 -rw-r--r--  1 me me  0 Dec 16 21:34 x

これで、ファイルは切り捨てられます(サイズ0、ディスクで使用されるスペースなし)。

$ echo >&3
$ ls -ls x
200 -rw-r--r--  1 me me  100001 Dec 16 21:34 x

オフセット100000でファイルに1バイトを書き込むと、ファイルのサイズは100001バイトになり、最初のファイルはすべてゼロで、HFS +では100k以上を使用しますが、他のほとんどのUnixファイルシステムでは約1ディスクブロック

一方、次の場合:

$ exec 3>> x
$ yes | head -n 50000 >&3
$ ls -ls x
200 -rw-r--r--  1 me me  100000 Dec 16 21:35 x
$ : > x
$ echo >&3
$ ls -ls x
8 -rw-r--r--  1 me me  1 Dec 16 21:36 x

オフセット100000ではなく、ファイルの最後に1バイトをファイルに書き込みますO_APPEND。ファイルは1バイトの大きさで、その1バイトを保持するのに必要なスペースを取ります。


1
この答えから多くを学びました。ありがとう。
chb
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.