Сценарий оболочки Unix для обрезки большого файла

87

Я пытаюсь написать сценарий Unix, который будет обрезать / очищать файл, который постоянно записывается / открывается приложением, когда он достигает, скажем, 3 ГБ пространства. Я знаю, что это сделает следующая команда:

cp /dev/null [filename]

Но я собираюсь запустить это в производственной среде автоматически как задание cron - просто разместите здесь сообщение, чтобы узнать, не столкнулись ли вы с какими-либо проблемами при выполнении чего-то похожего.

Peedee
источник
Это прод. журналы не имеют значения? Мне посчастливилось хранить свои производственные журналы в течение года + (в формате bzip2 -9 fmt), и у меня было несколько небольших утилит, которые упростили извлечение времени выполнения заданий, обработанных записей, а при загрузке в электронную таблицу было легко рассчитать и построить графики коэффициентов загрузки и еще много чего. Мы обнаружили проблему с hdwr из-за падения коэффициента загрузки. Да, существуют прекрасные инструменты для мониторинга, поэтому все зависит от вашей ситуации. КАК ОТДЕЛЬНЫЙ ВАРИАНТ, как вы видели logrotate, он может дать вам некоторую ценность (но раздражает при его настройке (просто догадываюсь)!).
shellter
5
Обратите внимание, что если файл журнала открыт с флагом O_APPEND, то усечение эффективно. Если он не открыт с флагом O_APPEND, программа продолжит запись со смещением 3 ГиБ (в первый раз); система будет рассматривать первые 3 ГиБ как полностью нулевые байты (что хорошо сжимается), но файл продолжит расти. Все зависит от программы, которая ведет журнал.
Джонатан Леффлер,

Ответы:

116

Просто чтобы добавить еще один ответ,

: > filename

: не работает в bash (совместим с POSIX), поэтому по сути он просто открывает файл для записи (что, конечно, усекает файл), а затем немедленно закрывает его.

РЕДАКТИРОВАТЬ: как прокомментировал шелтер, вам действительно не нужна команда для перенаправления:

$ echo foo > foo.txt
$ cat foo.txt
foo
$ > foo.txt
$ cat foo.txt
$

Простое перенаправление само по себе очистит файл.

Чепнер
источник
25
или просто > filename(как я уверен, вы знаете). Всем удачи.
shellter
5
@shelter "$> file" не POSIX и не переносимый. Вы должны использовать команду no-op ":" перед перенаправлением, как было предложено изначально.
Aaron Toponce 02
2
+ плюс за смайлик
Крис Сушиньски
2
Как заметил @AaronToponce, "$> file" действительно не переносится; в моей настройке Zsh он заставляет оболочку зависать (предположительно, ожидая ввода). "$:> file" отлично работает в Zsh.
Линус Арвер,
1
@TechEnthusiast Это зависит от ваших ожиданий. Само усечение является атомарным, но вы действительно не знаете, когда оно произойдет относительно какой-либо конкретной записи. Вы можете, например, закончить с неполной строкой в ​​начале файла.
chepner 05
65

Я использовал следующую команду в debian

truncate -s 0 filename
Рикардо Маримон
источник
@SteveClay: sudo sh -c ': > filename'также будет усекатьfilename
Perleone
2
@SteveClay ППО предложение также работает безупречно sudo: sudo cp /dev/null filename. Также cpпереносится, пока truncateесть только современный Linux.
Tino
11

Мне это кажется разумным. Unix, конечно, позволяет сделать это примерно 50 различными способами. Например,

echo -n "" >filename
cat /dev/null >filename
Дон Брэнсон
источник
2

trunc filename

работает на AIX версии UNIX

Сан
источник