Зачем вам кататься / 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' и '> wtmp' имеют одинаковый эффект.
Они действительно есть; слишком плохо cat /dev/null
было сохранено в коде.
Это означает, что следующий код будет работать со всеми распространенными оболочками ( csh
и sh
семействами):
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
и это будет работать со всеми оболочками , используя синтаксис Bourne, как ash
, bash
, ksh
, zsh
и любит:
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
Однако обратите внимание, что с древними оболочками Борна до POSIX любая из этих команд, в том числе cat /dev/null
не будет обрезать файл, если он будет записан потом еще работающим сценарием оболочки, добавляющим к нему. Вместо файла нулевого байта это будет разреженный файл с неизменным размером. То же самое произойдет, если файл будет записан процессом, ищущим позицию, которую он считает текущей, перед записью.
Помните также, что некоторые альтернативные решения, часто предлагаемые для усечения файла, имеют недостатки.
Оба из следующих просто не делают работу. Полученный файл не пустой, но содержит пустую строку. Это сломало бы лог-файлы, wtmp
которые хранят записи фиксированной ширины.
echo > file
echo "" > file
Следующий, основанный на sh
опции BSD, не переносимый, POSIX не указывает никаких разрешенных опций для echo, поэтому вы можете получить файл, содержащий строку с " -n
":
echo -n > file
Это тоже не переносимо с помощью sh
escape-последовательности System V. Некоторые оболочки создают файл, содержащий строку с " \c
":
echo "\c" > file
Тот использует команду, предназначенную для работы. Проблема в том, что truncate
она не переносима, поскольку эта команда, не указанная в POSIX, может отсутствовать в системе Unix / Linux.
truncate -s 0
Наконец, вот пара альтернатив, которые являются портативными и будут правильно выполнять свою работу:
Явная печать пустой строки в файл:
printf "" > file
Используя true
команду, которая строго эквивалентна команде no-op, :
хотя и более читабельной:
true > file