GNU/Linux >> Linux の 問題 >  >> Linux

使用中のファイルの切り捨て (Linux)

coreutils 7.0 の時点で、truncate があります。 コマンド。


これらの再成長したファイルの興味深い点は、/dev/null をコピーしてファイルを切り捨てた後、最初の 128 KB 程度がすべてゼロになることです。 その上。これは、ファイルが長さ 0 に切り詰められているために発生しますが、アプリケーションのファイル記述子は最後の書き込みの直後を指しています。再度書き込みを行うと、ファイル システムはファイルの先頭をすべてゼロ バイトとして扱います - 実際にゼロをディスクに書き込むことはありません。

理想的には、アプリケーションのベンダーに O_APPEND でログ ファイルを開くよう依頼する必要があります。 国旗。これは、ファイルを切り捨てた後、次の書き込みで暗黙的にファイルの最後までシークし (オフセット ゼロに戻ることを意味します)、新しい情報を書き込むことを意味します。

このコードは標準出力をリグするため、O_APPEND になります。 mode を実行し、その引数で指定されたコマンドを呼び出します (むしろ nice のように) nice レベル、または nohup を調整した後にコマンドを実行します 修正後にコマンドを実行するため、SIGHUP は無視されます)。

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>

static char *arg0 = "<unknown>";

static void error(const char *fmt, ...)
{
    va_list args;
    int errnum = errno;
    fprintf(stderr, "%s: ", arg0);
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    if (errnum != 0)
        fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
    putc('\n', stderr);
    fflush(0);
    exit(1);
}

int main(int argc, char **argv)
{
    int attr;
    arg0 = argv[0];

    if (argc < 2)
        error("Usage: %s cmd [arg ...]", arg0);
    if ((attr = fcntl(1, F_GETFL, &attr)) < 0)
        error("fcntl(F_GETFL) failed");
    attr |= O_APPEND;
    if (fcntl(1, F_SETFL, attr) != 0)
        error("fcntl(F_SETFL) failed");
    execvp(argv[1], &argv[1]);
    error("failed to exec %s", argv[1]);
    return(1);
}

私のテストは幾分カジュアルでしたが、それが機能することを私に納得させるにはかろうじて十分でした.

もっと簡単な方法

ビリーは答えの中で「>>」と述べています ' は追加演算子です。実際、Solaris 10 では、bash (バージョン 3.00.16(1)) は O_APPEND を使用します。 フラグ - したがって、上記のコードは不要になります (「Black JL:」は、このマシンでの私のプロンプトです):

Black JL: truss -o bash.truss bash -c "echo Hi >> x3.29"
Black JL: grep open bash.truss
open("/var/ld/ld.config", O_RDONLY)             Err#2 ENOENT
open("/usr/lib/libcurses.so.1", O_RDONLY)       = 3
open("/usr/lib/libsocket.so.1", O_RDONLY)       = 3
open("/usr/lib/libnsl.so.1", O_RDONLY)          = 3
open("/usr/lib/libdl.so.1", O_RDONLY)           = 3
open("/usr/lib/libc.so.1", O_RDONLY)            = 3
open("/platform/SUNW,Ultra-4/lib/libc_psr.so.1", O_RDONLY) = 3
open64("/dev/tty", O_RDWR|O_NONBLOCK)           = 3
stat64("/usr/openssl/v0.9.8e/bin/bash", 0xFFBFF2A8) Err#2 ENOENT
open64("x3.29", O_WRONLY|O_APPEND|O_CREAT, 0666) = 3
Black JL:

上記のラッパー ('cantrip') コードではなく追加リダイレクトを使用してください。これは、ある特定の手法を他の (有効な) 目的に使用する場合、それを別の手法に適応させることは、たとえ機能していても、必ずしも最も単純なメカニズムではないことを示しています。


> の代わりに>> を使用して出力をリダイレクトします。これにより、ファイルが元のサイズに戻ることなく、ファイルを切り詰めることができます。また、STDERR (2>&1) をリダイレクトすることを忘れないでください。

したがって、最終結果は次のようになります:myprogram >> myprogram.log 2>&1 &


Linux
  1. Linuxファイルパーミッションの基本

  2. Linux –すべてがファイルですか?

  3. ソースが安全に更新されている間にRsyncを使用していますか?

  1. Linuxでファイルを移動する方法

  2. Linuxファイルのアクセス許可について

  3. Linux で select が使用される理由

  1. Linuxテールコマンド

  2. Linuxタッチコマンド

  3. LinuxでのCatコマンド