Очистка содержимого текстового файла

16

У меня есть текстовый файл в моем домашнем каталоге, который регулярно получает данные через задание cron. Поскольку задание cron предоставляет динамические данные, я также хотел бы установить задание cron для очистки содержимого файла (файл должен все еще существовать). Мне не нужна помощь с cron, только команда, которая может помочь с очисткой файла.

sosytee
источник
5
Альтернатива: tail -n +1000 file.txt > file.txtследует удалить 1000 строк и сохранить самые новые строки в файле (вы никогда не знаете, когда вам может понадобиться какая-то последняя запись для отслеживания чего-либо).
Rinzwind,
2
На самом деле это лучший вариант, чем очистка файла по расписанию.
Бруно Перейра
1
@Rinzwind, это не сработает, так как файл будет обрезан до того, как tail попытается его прочитать. Вам нужно перенаправить на новый файл, а затем заменить оригинальный на новый.
Псуси
Правда @psusi :) там должен быть дополнительный редирект там.
Rinzwind

Ответы:

28

Самый простой способ:

> filename

Это менее очевидный способ и, вероятно, менее читаемый другими пользователями в сценарии оболочки, но это все, что вам нужно.

Потому >что на самом деле это не действительно команда (это встроенная команда bash), которую вы не можете использовать:

sudo > filename

когда у вас нет разрешений на этот файл. Но вы можете использовать:

sudo bash -c "> filename"
Раду Рэдяну
источник
какие разрешения необходимо изменить, поскольку в нем говорится, что разрешение запрещено, я уже выполнил chmod 755 для файла, или я должен сделать его новым сообщением (я имею в виду вопрос разрешений)
sosytee
@sosytee Смотрите мои новые правки.
Раду Рэдяну
1
@sosytee Конечно вы можете, но используйте sudo crontab -eдля добавления задания cron для root, а не для вас. Или изменить разрешение файла на 766 (или 666), а не 755: sudo chmod 766 filename. Подробнее о: codex.wordpress.org/Changing_File_Permissions
Раду Радеану
1
truncate filenameнемного чище и проще, чем перенаправление пустого вывода в файл и не сталкивается с проблемами с sudo.
psusi
1
@psusi truncate -s 0 filenameдействительно может сделать трюк. Вы можете добавить это как ответ.
Раду Рэдяну
19

Для этого создан инструмент:

truncate -s 0 filename

Это очистит содержимое, но это будет тот же файл ( индекс останется прежним).

Это важно, потому что некоторые программы хранят дескриптор файла «по индексу». Предположим, вы «очистили» файл, используя наивный метод удаления и повторного создания файла. Некоторые программы могут по-прежнему хранить дескриптор старого файла (со старым содержимым), даже если он больше не виден обычными средствами, например ls.

Некоторые ссылки на более подробную информацию в конце этого ответа.


Другой способ, может быть, легче запомнить:

echo -n > filename

Это также сохраняет тот же индекс.

Обратите внимание, что оба truncateи echo -nне определены POSIX .

Для соответствия POSIX используйте cat /dev/null:

cat /dev/null > filename

Еще один способ, более неясный и, вероятно, не агностический:

> filename

Если для усечения файла требуются права суперпользователя для записи, следующие строки будут работать не так, как ожидается:

sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename

Это связано с тем, что перенаправление выполняется оболочкой еще до выполнения sudo. Это означает, что доступ для записи в файл осуществляется с использованием привилегий пользователя, который запускает оболочку, а не привилегий, которые будут предоставлены sudo.

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

sudo sh -c "echo -n > filename"

Использование truncateне требует такого обходного пути, потому что доступ на запись осуществляется не оболочкой, а с truncateпомощью sudo с использованием привилегий sudo.

sudo truncate -s 0 filename

Для некоторых подробностей о программах, которые держат файл открытым, даже если файл был удален, вы можете прочитать следующее:

lesmana
источник
в нем говорится, что разрешение отклонено, использовалось имя файла chmod 755, но разрешение все равно отклонено
sosytee
2
возможно у вас в bash включен noclobber?
Lesmana
Самый полный ответ на данный момент
AbdelHady
4

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

Посмотрите здесь, как настроить logrotate: http://linuxcommand.org/man_pages/logrotate8.html

piotrektt
источник
1
Я предпочитаю этот вариант сам. Мы используем «файл> 10 Мб» -> «tar.gz это для резервного копирования» «пустой файл». И резервные копии удаляются через 900 дней.
Rinzwind
3

echo "" > foo_fileэто простой способ сделать это, он заменит все содержимое foo_file на "", делая его в этом случае пустым.

Вы также можете использовать cat /dev/null > foo_file, который будет читать нулевое устройство и перезаписывать ваш файл вообще ни с чем.

Бруно Перейра
источник
в нем говорится, что разрешение отклонено, используется имя файла chmod 755, но разрешение все равно отказано
sosytee
Можете ли вы прочитать права доступа к файлу с вашим обычным пользователем, пожалуйста?
Бруно Перейра
да, я могу читать содержимое как обычный пользователь
sosytee