кошка/dev/null освободила мой файл журнала, но размер не изменился

Методы Shell

При выполнении команды в оболочке, можно узнать PID последнего процесса, который был выполнен в фоновом режиме с помощью специальной переменной $! в оболочке Bash.

Например:

$ sleep 5 &
$ echo $!
8648

Также, когда Вы фон процесс PID того процесса возвращаетесь через консоль как это:

$ sleep 5 &
[1] 8648    

Другой метод должен был бы использовать pgrep -P <PPID>. Например:

# PID of bash shell
$ echo $$
8376

# run fake job
$ sleep 120 &
[1] 8891

# pgrep PPID
$ pgrep -P 8376
8891

valgrind

Существует другой метод, если можно ввести следующее перед осуществлением программы, Вы пытаетесь получить дочерний PIDs к:

$ valgrind --trace-children=yes <cmd>

Например:

# sample.bash
#/bin/bash

ls

$ valgrind --trace-children=yes ./sample.bash
...
==17734==      possibly lost: 0 bytes in 0 blocks
==17734==    still reachable: 33,606 bytes in 95 blocks
==17734==         suppressed: 0 bytes in 0 blocks
==17734== Rerun with --leak-check=full to see details of leaked memory
==17734== 
==17734== For counts of detected and suppressed errors, rerun with: -v
==17734== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
==17733== 
==17733== HEAP SUMMARY:
==17733==     in use at exit: 36,409 bytes in 879 blocks
...

Эти 17733 являются PPID, и PID 17734 является дочерний PID, которые добираются, вызвал (ls).

4
29.07.2014, 01:45
3 ответа

cat / dev / null - операция no no op, поскольку она ничего не выводит. cp / dev / null file также бессмысленно.

Более простой способ очистить содержимое файла - это перенаправить на него нулевую команду таким образом:

: > file

или даже, с большинством оболочек, использовать только перенаправление без указания какой-либо команды:

> file  

Тот факт, что размер сообщается ls по-прежнему высокий, просто из-за процесса записи, стремящегося к ожидаемому представлению о том, каким должен быть конец файла перед записью. Поскольку перед точкой поиска нет ничего, это не должно повредить. Единственный риск будет заключаться в том, что вы захотите сделать резервные копии или копии затронутого файла с помощью инструмента, не поддерживающего разреженные файлы.

Обратите внимание, что перезапуск процесса записи не «освободит» пространство, поскольку файл останется «дырявым».

Если вы действительно хотите обнулить сообщаемый размер файла, вам необходимо остановить (прервать) процесс записи перед тем, как очистить файл.

10
27.01.2020, 20:44

Предполагая, что вы хотели сказать

cat /dev/null > file_log.txt

или

cp /dev/null file_log.txt

, что имеет тот же эффект в этом отношении, ответ заключается в том, что процесс, открывший файл для запись выполнялась без O_APPEND , или она произвольно устанавливает смещение в файл, и в этом случае создается разреженный файл .

На странице руководства для write (2) это довольно ясно объясняется:

Для файла, доступного для поиска (т.е. того, к которому может применяться lseek (2), для например, обычный файл) запись происходит по смещению файла, и смещение файла увеличивается на фактическое количество байтов написано. Если файл был открыт (2) с помощью O_APPEND, смещение файла равно сначала устанавливается в конец файла перед записью. Регулировка смещения файла и операция записи выполняются атомарно.

Указанное смещение является свойством соответствующего файлового дескриптора процесса записи - если другой процесс усекает файл или записывается в файл, это не повлияет на смещение. (Более того, если тот же процесс откроет файл для записи без O_APPEND , он получит другой файловый дескриптор для этого, и запись в файл через новый файловый дескриптор будет иметь тот же эффект. .)

Предположим, что процесс P открывает файл для записи без добавления, получая дескриптор файла fd . Тогда влияние на размер файла (как сообщает stat () ) усечения файла (например, путем копирования в него / dev / null ) будет отменено, как только ] P записывает в fd . В частности, при write () в fd система переместится («ищет») на смещение, связанное с fd , заполняя пространство от текущего конца файл (возможно, в начало, если он был полностью усечен) до смещения с нулями. Однако, если за это время файл увеличился на , запись в fd перезапишет содержимое файла, начиная со смещения.

Разреженный файл - это файл, содержащий «дыры», т.е. система «знает», что существуют большие области с нулями, которые на самом деле не записываются на диск. Вот почему du и ls не согласны - du смотрит на фактическое использование диска, а ls просто использует stat () для извлечения атрибута размера файла.

Способ устранения: перезапустите процесс. Если возможно, перепишите часть, где открывается файл, чтобы использовать O_APPEND (или режим a при использовании fopen () ).

17
27.01.2020, 20:44

cat / dev / null file_log.txt

Это только заставляло cat читать / dev / null и немедленно читать file_log.txt и выводить результат на stdout , ваш экран. Это вообще ничего не удалит.

Если вы хотите протестировать, используйте cat / dev / null non_existent_file , и вы увидите, что это ошибка.

Правильный способ усечения файла - использование перенаправителей оболочки или любого другого редактора для удаления строк. Вы намеревались сделать следующее:

cat /dev/null > file_log.txt

, что объясняет первый метод.

3
27.01.2020, 20:44

Теги

Похожие вопросы