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

808
John

Я пытаюсь усечь файл, используемый для перенаправленного стандартного вывода. Например:

ping localhost>/tmp/test.log 

Если я звоню, rm /tmp/test.logто перенаправление прекращается, но команда работает.

Если я вызываю truncate -s0 /tmp/test.logили >/tmp/test.logили echo ..и и т. Д., Перенаправление работает, но файл содержит начальные нули, потому что позиция потока не изменилась.

Как я могу обрезать файл?

4
Обратите внимание, что `rm / tmp / test.log` удаляет запись файла из каталога, но сам файл все еще существует, занимает место и увеличивается в файловой системе на основе inode. Он будет действительно удален, когда он больше не используется, то есть когда ваш `ping` завершен или даже позже. Kamil Maciorowski 6 лет назад 1
Просто сделайте усечение частью вашей процедуры. Отправьте 10.000 пингов или что-то еще, удалите файл и напишите новый. Seth 6 лет назад 0
Что вы имеете в виду; что ты хочешь случиться? Вы хотите многократно пинговать свой `localhost` и постоянно обновлять` / tmp / test.log`, чтобы он содержал только статистику вывода из самого последнего ответа ICMP? tjt263 6 лет назад 0

2 ответа на вопрос

2
hymie

Вы должны понимать файловые системы Unix, прежде чем сможете ответить на этот вопрос.

Единственное, что rmнужно сделать, это стереть имя файла, фактически указатель с вашей структуры каталогов на блоки диска.

Когда ты бежишь

ping localhost > /tmp/test.log rm /tmp/test.log 

перенаправление не прекращается. Команда продолжает выполняться, и данные продолжают накапливаться в вашей области диска. У вас просто нет права доступа к этим данным, потому что вы стерли их имя.

Вы можете создать другой, совершенно не связанный файл с именем /tmp/test.log.

Как вы заметили, пытаясь усечь файл, вы избавляетесь от данных, которые были там раньше, но внутренний дескриптор файла знает позицию в файле, на которую он указывает, и записывает после конца файла расширение файла. Отсюда ведущие нули.

Если вы хотите «сбросить» перенаправление, то вам нужно убить pingпрограмму, стереть или обрезать /tmp/test.logфайл, а затем перезапустить pingпрограмму.

Вы также можете использовать такую ​​программу, как rotatelogs

ping localhost | rotatelogs ping.out.%Y%m%d.%H%M 600 

вращать файл журнала либо на основе истекшего времени или размера файла.

«У вас просто нет права доступа к этим данным, потому что вы стерли указатель файловой системы». В целом это не так. Хитрость заключается в использовании `/ proc // fd / 0` путь. Kamil Maciorowski 6 лет назад 0
0
Kamil Maciorowski

Планируйте заранее:

  1. Усечь или удалить файл, если он существует.
  2. Используйте >>вместо >.

Таким образом, вы воспользуетесь тем, что >>по сути «всегда стремитесь к концу файла», >сохраняя указатель на последнее записанное местоположение.

Тогда вы можете обрезать файл и >>будете подчиняться. Посмотрите мой ответ, он исследует точное поведение, которое вам нужно.

Похожие вопросы