Раньше в системах Linux я мог обрезать большие открытые файлы журналов (то есть файл, который активно записывается процессом) с использованием cat /dev/null > file.log
.
Тем не менее, на 10,9 (Mavericks), это не так. У меня есть файл размером 11 ГБ, в который регистрируется приложение, но когда я выполняю ту же команду с указанным файлом, кажется, ничего не происходит.
Когда я пробую это на файле тривиального размера, это работает.
Вот ls -l /dev/null
:
crw-rw-rw- 1 root wheel 3, 2 Dec 16 12:49 /dev/null
Я также пытался cp /dev/null file.log
безрезультатно.
Думая, что я мог бы воспользоваться функцией усечения ( man 2 truncate
в Дарвине), я скомпилировал это и запустил для него два файла, один из которых имеет тривиальный размер, а другой - сам файл журнала. Снова, это работало против тривиального файла и не работало на намного большем журнале.
/*
* Copyright (c) 2013 Thomas de Grivel <thomas@lowh.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
...
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <unistd.h>
int main (int argc, const char **argv)
{
int e = 0;
while (--argc) {
argv++;
if (truncate(*argv, 0)) {
e = 4;
warn("%s", *argv);
}
}
return e;
}
Процесс возвращается 0
независимо от того, какой файл я использую.
du
илиdu -h
сказать? Возможно ли, что файл является разреженным файлом?du -h /tmp/file.log
Результаты:11G /tmp/file.log
Ответы:
cat /dev/null
немного запутанный способ написать команду, которая не производит вывод.:
илиtrue
более очевидные.Во всех
cat /dev/null > file
,: > file
и даже> file
в большинстве оболочек, оболочка открывает файл с O_TRUNC на стандартный вывод, а затем запускает приложение , которое не делает ничего выводить, то файл закрывается и слева усечен.Однако в этом случае или при использовании
truncate
системного вызова, если процесс, заполняющий этот файл, не открыл его с флагом O_APPEND, при следующей записи в дескриптор файла, который он открыл в файле, он запишет данные со смещением были внутри файла.Поскольку HFS + не поддерживает разреженные файлы, это означает, что пространство до этого смещения должно быть перераспределено и заполнено нулями системой.
Итак, вам нужно убить приложение, которое пишет в этот файл, перед его усечением. Или вам нужно убедиться, что приложение открывает файл с помощью
O_APPEND
(например, с>>
помощью перенаправления оболочки).Если вы хотите поэкспериментировать с этим:
Теперь fd 3 моей оболочки составляет 100000 байт в файле
Теперь файл урезан (размер 0, на диске нет места).
Записывая 1 байт в файл со смещением 100000, размер файла теперь составляет 100001 байт, первые из них, все нули, будут использовать более 100 Кбайт в HFS +, но примерно в одном блоке диска в большинстве других файловых систем Unix.
С другой стороны, с:
Запись 1 байта в файл не по смещению 100000, а в конце файла из-за
O_APPEND
. Файл имеет размер 1 байт и занимает место, необходимое для хранения этого одного байта.источник