Как ведут себя открытые файлы в системах Linux?

17

Я просто переименовал файл журнала в «foo.log.old» и предположил, что приложение начнет запись нового файла журнала в «foo.log». Я был удивлен, обнаружив, что он отслеживает лог-файл с новым именем и продолжает добавлять строки в "foo.log.old".

В Windows я не знаком с таким поведением - я даже не знаю, возможно ли вообще его реализовать. Как именно это поведение реализовано в Linux? Где я могу узнать больше об этом?

ripper234
источник
Я не воспринимаю это как ответ, потому что не знаю, но думаю, что это связано с тем, что inode не изменяется при перемещении файла.
mathepic

Ответы:

20

Программы подключаются к файлам через номер, поддерживаемый файловой системой (называемый inode в традиционных файловых системах unix), имя которого является просто ссылкой (и, возможно, не уникальной ссылкой в ​​этом случае).

Итак, несколько вещей, о которых нужно знать:

  1. Перемещение файла с помощью mvэтого значения не изменит этого нижележащего числа, если только вы не переместите его по файловым системам (что эквивалентно использованию cpзатем rmна оригинале).
  2. Поскольку к одному файлу может быть подключено более одного имени (т. Е. У нас жесткие ссылки), данные в «удаленных» файлах не исчезают, пока не исчезнут все ссылки на нижележащий файл.
  3. Возможно, самое важное: когда программа является openфайлом, она ссылается на него, что (для целей, когда данные будут удалены) эквивалентно наличию имени файла, связанного с ней.

Это вызывает несколько вариантов поведения, таких как:

  • Программа может openфайл для чтения, но на самом деле не читает его до тех пор, пока пользователь не rmотредактирует его в командной строке, и программа все равно будет иметь доступ к данным .
  • То, с чем вы столкнулись: mvиспользование файла не разрывает отношения между файлом и любыми программами, в которых он открыт (если вы не пересекаете границы файловой системы, в этом случае у программы все еще есть версия оригинала для работы).
  • Если программа openотредактировала файл для записи, и у пользователя rmесть последнее имя файла в командной строке, программа может продолжать помещать материал в файл, но как только он закроется, больше не будет ссылок на эти данные и это уйдет.
  • Две программы, которые обмениваются данными через один или несколько файлов, могут получить грубую частичную защиту, удалив файлы после их завершения open. (Это не настоящий разум безопасности, он просто превращает зияющую дыру в состояние гонки.)
dmckee
источник
1
Я согласен с @dmckee, я просто хотел заметить: программа может openфайл для чтения и записи (как то, что произошло с файлом журнала в вопросе).
Jsbillings
@jsbillings: Да, но есть риск. Если все имена файловых систем исчезли, вы можете записать ГБ в открытый файл, который испарится как утренняя роса, как только вы закроете его.
dmckee
1
Кроме того, inode копируется в ядро, и это то, что используется, а не копия диска. Таким образом, файл может быть mv'd или cp ', но открытый файл уже работает со структурами данных ядра, а не с версией диска. Поэтому, если вы скопируете другой файл в файл, открытый для записи, процесс все равно будет записывать в ту же относительную позицию, что и в старом файле. По этой причине программы, такие как Apache httpd, имеют обработчик сигналов, который закрывает и повторно открывает файлы журналов.
Arcege
0

Чтобы действительно увидеть, как реализовано это поведение, вы можете взглянуть на некоторые книги по программированию Unix. Mathepic прав в том, что он связан с inode. Фактическое имя пути используется только для открытия файла, как только это будет сделано, программа ссылается на него по открытому дескриптору файла. Дескриптор файла, в свою очередь, ссылается на индекс, который в данном случае не заботится об изменении имени базового файла.

Что касается реализации этого в Windows, это вопрос для другого сайта.

Чтобы узнать об этом больше, не обращая внимания на книги, просто ищите файловые системы и inode in-linux. Там может быть не четкий ответ, но вы сможете понять, почему.

Мистер Шикаданс
источник
4
«Поиск вокруг - вы, вероятно, не найдете хорошего ответа, но поймете его» - не очень хороший ответ.
Mattdm