В Интернете многие люди говорят, что вы можете обрезать файл, используя > filename
или truncate -s0 filename
пока файл начинает использоваться
Я знаю, что каждый раз, когда процесс записывает в файл, процесс использует смещение для записи в файл, выполняя тест со скриптом, подобным этому.
#!/usr/bin/env python
import os, time
with open("passwd","w") as f: #copy of passwd file in my current directory
f.seek(0)
for x in xrange(1,1000):
f.write("hello world \n" + time.ctime() + "\n")
f.flush()
time.sleep(2)
каждый раз, когда мой сценарий выполняет системный вызов записи, смещение в поле /proc/pid_number/fdinfo/3 pos
изменяется, но когда я пытаюсь обрезать файл с помощью метода, описанного выше, в моем файле я вижу много символов, подобных этому ^@
когда я открываю файл с помощью vim
или менее -u
и тип файла меняется с ASCII text
на data
а когда я использую ls -l filename
размер не изменяется
Таким образом, при усечении файла смещение файла не сообщается, я проверяю это в Centos 7
и Redhat 5
, поэтому я могу сказать, что изменился размер файла, когда файл используется процессами, не освобождает место и испачкать мой файл.
Итак, мои вопросы: если у моего процесса есть открытый файл в pos 1000
и я сделал truncate -s0 filename
, если усечение работает, что происходит в следующей записи процесса?
strace truncate -s0 passwd
open("passwd", O_WRONLY|O_CREAT|O_NONBLOCK, 0666) = 3
ftruncate(3, 0) = 0
close(3) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
ls -l passwd
-rw-rw-r--. 1 user91 users 13832 Feb 23 17:16 passwd
Как видите, мой файл не был усечен
Эта проблема не возникает, если я открываю в режиме добавления, например, с этим кодом.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
int main(){
int range = 1000;
int x; x = open("passwd", O_WRONLY|O_CREAT|O_APPEND);
int i = 0;
for( i = 0; i <= range; range++)
write(x,"hello world\n",12);
sleep(2);
}