Зачем вам кататься /dev /null на что-нибудь?
Вы сделаете это, чтобы обрезать содержимое файла, не затрагивая индекс. Все программы, в которых этот файл открыт для чтения или записи, не будут затронуты, за исключением того, что размер файла будет сброшен на ноль.
Часто встречается фиктивная альтернатива - удаление файла, а затем его создание:
rm file
touch file
или подобное:
mv file file.old
gzip file.old
touch file
Проблема заключается в том, что эти методы не предотвращают запись старого файла какими-либо процессами, у которых удаленный файл открыт во время удаления. Причина заключается в том, что в файловых системах Unix при удалении файла вы только отсоединяете его имя (путь) от его содержимого (inode). Индод сохраняется, пока существуют процессы, в которых он открыт для чтения или записи.
Это приводит к нескольким негативным последствиям: журналы, записанные после удаления файла, теряются, поскольку не существует простого / портативного способа открыть удаленный файл. Пока процесс выполняет запись в удаленный файл, его содержимое все еще использует пространство в файловой системе. Это означает, что если вы удалите / создадите файл, потому что он заполнил ваш диск, диск останется заполненным. Один из способов решения этой последней проблемы - перезапустить процессы регистратора, но вы, возможно, не захотите этого делать, поскольку критически важные службы и промежуточные журналы будут окончательно потеряны. Существуют также побочные эффекты, связанные с тем, что создаваемый файл может не иметь таких же прав доступа, владельца и группы, как у исходного. Это, например, может помешать анализатору журналов читать вновь созданный файл, или, что еще хуже, запретить процессу журналирования записывать собственные журналы.
Первый метод, cat /dev/null > file
достигает цели должным образом, однако, несмотря на упорную городскую легенду, его часть cat /dev/null
не делает абсолютно ничего полезного. Он открывает псевдо-файл, который пуст по своей структуре, он не может ничего прочитать из него и, наконец, просто завершается. Использование этой команды в таком случае является пустой тратой нажатий клавиш, байтов, системных вызовов и циклов ЦП, и ее можно заменить без каких-либо функциональных изменений несомненно более быстрой командой no-op :
или даже, с большинством оболочек, вообще никакой командой.
Позвольте мне попробовать метафору, чтобы объяснить, насколько бесполезен cat /dev/null
. Допустим, ваша цель - опустошить стакан.
Сначала вы удалите из него любую жидкость. Этого достаточно, и это именно то, что (> file
) делает, учитывая, что перенаправления факта всегда обрабатываются первыми.
Затем вы выбираете пустую бутылку (/dev/null
) и выливаете ее в пустой стакан (cat
). Это бессмысленный шаг ...
Если вы прочитаете связанный документ до конца, вы можете заметить комментарии в этой строке от расширенной версии скрипта:
cat /dev/null > wtmp # ': > wtmp' and '> wtmp' have the same effect.
Они действительно есть; очень плохой cat /dev/null
был сохранен в коде.
Это означает, что следующий код будет работать со всеми распространенными оболочками (семейства csh
и sh
):
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
и это будет работать со всеми оболочками, использующими синтаксис Борна, такими как ash
, bash
, ksh
, zsh
и подобные:
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
Однако обратите внимание, что в древних оболочках Борна до POSIX любая из этих команд, в том числе cat /dev/null
, не будет обрезать файл, если впоследствии он будет записан все еще работающим сценарием оболочки, добавляющим его. Вместо файла нулевого байта это будет разреженный файл с неизменным размером. То же самое произойдет, если файл будет записан процессом, ищущим позицию, которую он считает текущей, перед записью.
Помните также, что некоторые альтернативные решения, часто предлагаемые для усечения файла, имеют недостатки.
Оба из следующих просто не делают работу. Полученный файл не пустой, но содержит пустую строку. Это сломало бы файлы журнала, такие как wtmp
которые хранят записи фиксированной ширины.
echo > file
echo "" > file
Следующий, основанный на опции BSD sh
не является переносимым, POSIX не указывает никаких разрешенных опций для echo, поэтому вы можете получить файл, содержащий строку с « -n
»:
echo -n > file
Это тоже не переносимо с помощью escape-последовательности System V sh
. Некоторые оболочки создают файл, содержащий строку с « \c
»:
echo "\c" > file
Тот использует команду, предназначенную для работы. Проблема в том, что truncate
не является переносимым, поскольку эта команда, не указанная в POSIX, может отсутствовать в системе Unix/Linux.
truncate -s 0
Наконец, вот пара альтернатив, которые являются портативными и будут правильно выполнять свою работу: