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 &