TL; DR
Öffnen Sie Ihre Protokolldatei im Anhänge- Modus:
cmd >> log
Dann können Sie es sicher abschneiden mit:
: > log
Einzelheiten
Bei einer Bourne-ähnlichen Shell gibt es drei Möglichkeiten, wie eine Datei zum Schreiben geöffnet werden kann. In write-only ( >
), read + write ( <>
) oder append (und write-only,>>
) Modus.
In den ersten beiden merkt sich der Kernel Ihre aktuelle Position (von Ihnen meine ich die offene Dateibeschreibung) , die von allen Dateideskriptoren geteilt wird, die sie dupliziert oder geerbt haben, indem sie von abgezweigt wurden, auf der Sie die Datei geöffnet haben) Datei.
Wenn Sie das tun:
cmd > log
log
ist im schreibgeschützten Modus von der Shell für die Standardausgabe von geöffnet cmd
.
cmd
Wenn Sie in ihre Standardausgabe schreiben, schreiben Sie an die aktuelle Cursorposition, die in der geöffneten Dateibeschreibung enthalten ist sie für diese Datei freigeben.
Wenn Sie zum Beispiel cmd
anfänglich schreiben zzz
, befindet sich die Position bei Byte-Offset 4 in der Datei und beim nächsten Malcmd
oder die untergeordneten Elemente in die Datei geschrieben werden, werden die Daten dort geschrieben, unabhängig davon, ob die Datei im Intervall gewachsen oder geschrumpft ist .
Wenn die Datei verkleinert wurde, z. B. wenn sie mit einem abgeschnitten wurde
: > log
und cmd
schreibt xx
, diejenigen xx
geschrieben wird bei Offset 4
, und die ersten drei Zeichen durch NUL - Zeichen ersetzt werden.
$ exec 3> log # open file on fd 3.
$ printf zzz >&3
$ od -c log
0000000 z z z
0000003
$ printf aaaa >> log # other open file description -> different cursor
$ od -c log
0000000 z z z a a a a
0000007
$ printf bb >&3 # still write at the original position
$ od -c log
0000000 z z z b b a a
0000007
$ : > log
$ wc log
0 0 0 log
$ printf x >&3
$ od -c log
0000000 \0 \0 \0 \0 \0 x
0000006
Das bedeutet, dass Sie eine Datei, die nur im Schreibmodus geöffnet wurde (und dies gilt auch für Lesen + Schreiben ), nicht abschneiden können Datei (diese Dateien, mit Ausnahme von OS / X, belegen normalerweise keinen Speicherplatz auf der Festplatte, sondern werden zu spärlichen Dateien).
Stattdessen (und Sie werden feststellen, dass die meisten Anwendungen dies tun, wenn sie in Protokolldateien schreiben), sollten Sie die Datei im Anhänge- Modus öffnen :
cmd >> log
oder
: > log && cmd >> log
wenn Sie mit einer leeren Datei beginnen möchten.
Im Anhänge-Modus werden alle Schreibvorgänge am Ende der Datei ausgeführt, unabhängig davon, wo sich der letzte Schreibvorgang befand:
$ exec 4>> log
$ printf aa >&4
$ printf x >> log
$ printf bb >&4
$ od -c log
0000000 a a x b b
0000005
$ : > log
$ printf cc >&4
$ od -c log
0000000 c c
0000002
Das ist auch sicherer, als hätten zwei Prozesse versehentlich die Datei geöffnet (zum Beispiel, wenn Sie zwei Instanzen desselben Daemons gestartet haben), so dass sich deren Ausgabe nicht gegenseitig überschreibt.
Auf neueren Versionen von Linux, können Sie die aktuelle Position überprüfen und ob ein Dateideskriptor in geöffnet war append - Modus an , indem Sie /proc/<pid>/fdinfo/<fd>
:
$ cat /proc/self/fdinfo/4
pos: 2
flags: 0102001
Oder mit:
$ lsof +f G -p "$$" -ad 4
COMMAND PID USER FD TYPE FILE-FLAG DEVICE SIZE/OFF NODE NAME
zsh 4870 root 4w REG 0x8401;0x0 252,18 2 59431479 /home/chazelas/log
~# lsof +f g -p "$$" -ad 4
COMMAND PID USER FD TYPE FILE-FLAG DEVICE SIZE/OFF NODE NAME
zsh 4870 root 4w REG W,AP,LG 252,18 2 59431479 /home/chazelas/log
Diese Flags entsprechen den O ..._-Flags, die an den open
Systemaufruf übergeben wurden.
$ gcc -E - <<< $'#include <fcntl.h>\nO_APPEND O_WRONLY' | tail -n1
02000 01
( O_APPEND
ist 0x400 oder oktal 02000)
So ist die Shell >>
die Datei mit öffnet O_WRONLY|O_APPEND
(und 0.100.000 hier ist O_LARGEFILE, die diese Frage nicht relevant ist) , während >
ist O_WRONLY
nur (und <>
ist O_RDWR
nur).
Wenn Sie Folgendes tun:
sudo lsof -nP +f g | grep ,AP
Um nach Dateien zu suchen, die mit geöffnet sind O_APPEND
, finden Sie die meisten Protokolldateien, die derzeit auf Ihrem System zum Schreiben geöffnet sind.