Желательно записать EOF в файл, чтобы остановить все завершающие процессы.

Вы запутались. rmdir просто не заботится о количестве ссылок. Логика довольно проста.

Как только файл имеет счетчик ссылок , равный 0, и, кроме того, нет запущенных процессов со ссылкой (дескриптор файла или текущий каталог), он будет действительно удален. Это тот момент, когда дисковое пространство можно повторно использовать для чего-то другого [*].

Каталоги представляют собой файл. Но отключение (удаление их от родительского) требует большего внимания, чем другие типы файлов. Мы должны убедиться, что каждый дочерний элемент каталога также отключен. В противном случае мы можем потерять возможность обновить счетчик детских ссылок. Мы потеряем это дисковое пространство навсегда.

Поэтому мы не позволяем пользователям вызывать отключать каталог. Вместо этого они должны использовать специальный rmdir .Вызов rmdir отличается от unlink только двумя способами

  1. . Он требует, чтобы каталог был «пустым», что означает, что его единственные дочерние элементы являются стандартными . и .. записи.
  2. Перед тем, как запустить unlink в самом каталоге, он обязательно отключит эти две оставшиеся записи.

Это ит . Другой магии нет. rmdir не откладывается до тех пор, пока не будет выполнено условие в пункте 1. rmdir либо успешно, либо терпит неудачу в момент его вызова. Также условие никоим образом не основано на количестве ссылок.


Я нахожу эффект . запись о количестве ссылок интересна, хотя это не особый случай. Это жесткая ссылка на родительский каталог, поэтому количество ссылок в нем увеличивается. Это объяснение того, почему недавно созданный каталог DIR имеет счетчик ссылок 2. Если вы затем вызываете rmdir DIR , счетчик ссылок возвращается к 0, поскольку он удаляет обе ссылки DIR /. и DIR .


Linux фактически позволяет вам наблюдать за вышесказанным, запустив оболочку внутри каталога и запустив ls -ld после того, как каталог был отключен (удален из его родительского).

Конечно, ls -ld является сокращением для ls -ld. . . и .. продолжают работать даже после удаления записи каталога; на самом деле современный Linux не полагается на эти записи каталога на диске. Я ожидаю, что исходная реализация Unix не поддерживает это.Однако я считаю, что счетчик ссылок по-прежнему работал, как описано выше, и не имел особого случая для удаления каталога.

(Еще более интересно, как .. продолжает работать. Обсуждается в комментарии ниже).

На самом деле было бы очень легко взглянуть на исходный код Unix для rmdir . Он был реализован как пользовательская программа, работающая со специальными привилегиями . Исторический код unix легко найти в Интернете. Это одна из причин, по которой я так уверен в этом.


[*] Таким образом, вы можете увидеть, был ли удален файл, посмотрев разницу в используемом диске блоки в df. (или i-узлы в df -i. ). Этот подход хорошо работает в файловых системах, таких как Linux ext4 . Однако менее традиционные файловые системы могут иметь более сложную оптимизацию, что может затруднить наблюдение.

2
10.07.2017, 22:12
2 ответа

Мне это не кажется правильным способом достижения этого. Я думаю, вы хотите нацелить хвостовой процесс [es], читающий файл, а не сам файл. Вместо этого рассмотрите что-то вроде следующего.

ps -ef | grep "[t]ail" | grep 'somefile.log' | tr -s ' ' | cut -d' ' -f2 | xargs kill
  1. ps -efотобразит все процессы, запущенные в вашей системе.
  2. grep "[t]ail"найдет все процессы с хвостом в имени (, за исключением этого grep ).
  3. grep 'somefile.log'найдет среди них файлы с somefile.log в имени.
  4. tr -s ' 'сожмет все множественные пробелы до одного.
  5. cut -d' ' -f2будет использовать пробел в качестве разделителя, чтобы получить только второй столбец, который является PID.
  6. xargs killубьет этот PID.

Это убьет все хвостовые процессы, читающие файл (, за исключением некоторых странных угловых случаев, например. файл журнала с именем tailsomefile.log ). Может быть более чистый способ сделать это, но это было первое сразу очевидное решение для меня. Я проверил, что это работает в Linux.

1
27.01.2020, 22:03

Команда tail не завершает работу на EOF при запуске с -f в обычном файле. Он явно ожидает дополнительных данных. Итак, в конце вашего файла уже есть EOF -, он просто не приводит к выходу tail, потому что он не должен этого делать.

Единственный способ — убить хвост. Беги

ps ax|grep tail

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

pkill tail

чтобы убить все хвостовые процессы. Используйте это с осторожностью, так как вы можете убить процессы, которые вы не хотите убивать.

2
27.01.2020, 22:03

Теги

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