Ab Coreutils 7.0 gibt es einen truncate
Befehl.
Das Interessante an diesen nachgewachsenen Dateien ist, dass die ersten 128 KB oder so alle Nullen sind, nachdem Sie die Datei durch Kopieren von /dev/null
gekürzt haben darüber. Dies liegt daran, dass die Datei auf die Länge null gekürzt wird, der Dateideskriptor in der Anwendung jedoch immer noch unmittelbar nach dem letzten Schreibvorgang zeigt. Wenn es erneut schreibt, behandelt das Dateisystem den Anfang der Datei als reine Nullbytes – ohne die Nullen tatsächlich auf die Festplatte zu schreiben.
Idealerweise sollten Sie den Anbieter der Anwendung bitten, die Protokolldatei mit dem O_APPEND
zu öffnen Flagge. Das bedeutet, dass nach dem Abschneiden der Datei beim nächsten Schreibvorgang implizit bis zum Ende der Datei gesucht wird (dh zurück zum Offset Null) und dann die neuen Informationen geschrieben werden.
Dieser Code manipuliert die Standardausgabe so, dass sie sich in O_APPEND
befindet Modus und ruft dann den Befehl auf, der durch seine Argumente angegeben wird (eher wie nice
Führt einen Befehl aus, nachdem sein Nice-Level angepasst wurde, oder nohup
führt einen Befehl aus, nachdem die Dinge behoben wurden, sodass SIGHUP ignoriert wird).
#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);
}
Meine Tests waren etwas beiläufig, aber gerade genug, um mich davon zu überzeugen, dass es funktioniert.
Einfache Alternative
Billy merkt in seiner Antwort an, dass '>>
' ist der Append-Operator - und tatsächlich verwendet bash (Version 3.00.16(1)) unter Solaris 10 den O_APPEND
Flag - wodurch der obige Code unnötig wird, wie gezeigt ('Black JL:' ist meine Eingabeaufforderung auf dieser Maschine):
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:
Verwenden Sie die Anhängeumleitung anstelle des obigen Wrapper-Codes ('cantrip'). Dies zeigt nur, dass, wenn Sie eine bestimmte Technik für andere (gültige) Zwecke verwenden, die Anpassung an eine andere nicht unbedingt der einfachste Mechanismus ist - obwohl es funktioniert.
Leiten Sie die Ausgabe mit>> statt> um. Auf diese Weise können Sie die Datei kürzen, ohne dass die Datei auf ihre ursprüngliche Größe zurückwächst. Vergessen Sie auch nicht, STDERR (2>&1).
umzuleiten
Das Endergebnis wäre also:myprogram >> myprogram.log 2>&1 &