Everyone knows the truncate(file, size)
function, which changes the file size to a given size, by truncating the tail of the file. But how to do the same, only with the truncation of not the tail of the file and his head?

- 171
- 1
- 8
-
When the file is a logfile and the program writing to it keeps the filedescriptor open, no more logging will appear after moving the file. See https://unix.stackexchange.com/a/122942/57293 – Walter A Feb 11 '19 at 09:04
-
open the file, then `sendfile(fd, fd, &offset, size)`, I test on ubuntu 16, works ok, but the older kernel doesn't support – yuanjianpeng Jul 03 '19 at 06:47
3 Answers
Generally, you have to rewrite the entire file. The simplest way is to skip the first few bytes, copy everything else to a temporary file, and rename the temporary file on top of the old one when done. A more elaborate way is to rewrite it in place, analogous to how memmove
works, with read/seek/write/seek or pread/pwrite, and then truncate the last bit when done.
If you are on a recent version of Linux (>= 3.15), and you have a supported filesystem (currently ext4 or xfs), and the amount you wish to remove happens to be a multiple of the filesystem block size, you could use the non-portable fallocate(2)
with the FALLOC_FL_COLLAPSE_RANGE
flag. Note that this feature is not supported by the portable posix_fallocate
.

- 48,811
- 6
- 54
- 82
You could just use tail --lines=<linecount>
to always cap the log file to the last linecount
lines. This works if you're not trying to truncate to a specific / fixed file size.

- 31
- 1
The only way is to read the whole file and overwrite it from a needed position.

- 1,363
- 10
- 16