Видалення вмісту текстового файлу


16

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


5
Альтернативно: tail -n +1000 file.txt > file.txtслід видалити 1000 рядків і зберегти нові файли у файлі (ви ніколи не знаєте, коли вам знадобиться якийсь останній запис, щоб щось відстежувати).
Rinzwind

2
Це насправді кращий варіант, ніж очищення файлу у запланований час.
Бруно Перейра

1
@Rinzwind, це не буде працювати, оскільки файл буде усічений, перш ніж хвіст спробує його прочитати. Потрібно перенаправити на новий файл, а потім замінити оригінал на новий.
psusi

Правда @psusi :) там має бути додаткове перенаправлення.
Rinzwind

Відповіді:


28

Найпростіший спосіб:

> filename

Це менш очевидний спосіб і, ймовірно, менш читабельний у сценарії оболонки іншими, але це все, що вам потрібно.

Тому що >це насправді не дійсно команда (це bash вбудований), ви не можете використовувати:

sudo > filename

коли у вас немає дозволів на цей файл. Але ви можете використовувати:

sudo bash -c "> filename"

який дозвіл потрібно змінити, оскільки він говорить про відмову в дозволі, я вже зробив chmod 755 у файл, або я повинен зробити його новою публікацією (я маю на увазі питання дозволу)
sosytee

@sosytee Дивіться мої нові зміни.
Radu Rădeanu

1
@sosytee Звичайно, ви можете, але використовуйте, sudo crontab -eщоб додати роботу cron для root, а не для вас. Або змінити дозвіл файлу на 766 (або 666), а НЕ 755: sudo chmod 766 filename. Більше про: codex.wordpress.org/Changing_File_Permissions
Radu Rădeanu

1
truncate filenameтрохи чистіше і простіше, ніж перенаправлення порожнього виводу у файл і не стикається з проблемами sudo.
psusi

1
@psusi truncate -s 0 filenameсправді може зробити хитрість. Ви можете додати його як відповідь.
Radu Rădeanu

19

Для цього створений інструмент:

truncate -s 0 filename

Це очистить вміст, але все одно це буде той самий файл (the inode залишається таким же).

Це важливо, оскільки деякі програми містять ручку до файлу "by inode". Припустимо, ви "порожні" файли використовуєте наївний метод видалення та відтворення файлу. Деякі програми все ще можуть містити ручку до старого файлу (зі старим вмістом), навіть якщо він більше не видно за звичайні засоби, наприклад 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 truncate -s 0 filename

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


в ньому сказано, що в дозволі відмовлено, використовували ім'я файлу chmod 755, але все ще в дозволі відмовлено
sosytee

2
можливо у вас включений noclobber в bash?
lesmana

Найповніша відповідь поки що
АбдельХаді

4

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

Погляньте тут, як налаштувати logrotate: http://linuxcommand.org/man_pages/logrotate8.html


1
Я сам підтримую цей варіант. Ми використовуємо "файл> 10 Мб" -> "tar.gz для резервного копіювання" "порожнього файлу". А резервні копії видаляються через 900 днів.
Rinzwind

3

echo "" > foo_fileце простий спосіб зробити це, він замінить весь вміст foo_file на "" , що робить його в цьому випадку порожній.

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


там сказано, що в дозволі відмовлено, використано ім'я файлу chmod 755, але все ще в дозволі відмовлено
sosytee

Чи можете ви прочитати права доступу до файлу зі своїм звичайним користувачем?
Бруно Перейра

так, я можу прочитати вміст як звичайний користувач
sosytee
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.