Почему каталог может быть удален, если моя оболочка использует этот каталог?

Почему каталог может быть удален, если моя оболочка использует этот каталог?

31.01.2020 08:50:44 Просмотров 32 Источник

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

У меня был мой shell cd'D внутри подкаталога git repo, и я выполнил git rebase -isquash, в которой коммиты включали создание этого каталога.

После того, как эта операция завершилась без инцидентов, оболочка стала в осиротевшем состоянии, где состояние git status(ни в zsh theme helper RPROMPT, ни при запуске) указывало,что я больше не был даже в репозитории git.

Однажды я запустил cd ..все было прекрасно, и все это имело смысл. В ходе операции перебазирования Git восстановил rmкотором я находился (на первом этапе перебазирования), а затем вернул его обратно. Поскольку он был возвращен, я также мог запустить cd $(pwd), чтобы добраться туда за один шаг.

Это какое-то непонятное поведение. Хотя, не ясно, что технически git сделал что-то не так. Мой вопрос заключается в том, будет ли это ошибкой в git statusили пользователи должны знать, как справиться с этой ситуацией?

Кроме того, более широкий, актуальный корневой вопрос: почему разрешается удалять каталог, в котором находится моя оболочка, когда не разрешается извлекать диск, если у меня есть оболочка в смонтированном каталоге? Мне это кажется непоследовательным.

Дело в точку: fuser <directory> показывает текущую директорию. Если программа находится" на "каталоге, она "использует" его.

У вопроса есть решение - Посмотреть?

https://stackoverflow.com/questions/60008928/why-can-a-directory-be-removed-when-my-shell-is-using-that-directory#comment106128518_60008928
Я должен предположить, что, как и в этом ответе , возможность удалить что-то, пока оно используется, - это просто способ, которым оно должно работать, и это обязательно создает компромисс потенциальной путаницы, связанной с тем, что программа все еще имеет доступ к удаленной вещи. (В этом случае: оболочка, сохраняющая дескриптор на удаленном каталоге, как следствие git, разрешенного ОС для удаления этого каталога)

Ответы - Почему каталог может быть удален, если моя оболочка использует этот каталог? / Why can a directory be removed when my shell is using that directory?

phd

31.01.2020 09:03:16

Терминал 1:

$ cd tmp/
$ mkdir test
$ cd test

Терминал 2:

$ rmdir tmp/test 

Терминал 1:

$ ls 
sh: 0: getcwd() failed: No such file or directory

Непоследовательно, да. Но разрешили.

ПС. И это не имеет никакого отношения к git.

https://stackoverflow.com/questions/60008928/why-can-a-directory-be-removed-when-my-shell-is-using-that-directory/60009103#comment106128590_60009103
Да. Очень хорошо отметить, что это не имеет никакого отношения к git; я просто думаю, что кто-то столкнется с этим во время работы с git, и мои ключевые слова могут помочь им.
https://stackoverflow.com/questions/60008928/why-can-a-directory-be-removed-when-my-shell-is-using-that-directory/60009103#comment106138457_60009103
Нет необходимости во втором терминале. mkdir test; cd test; rmdir ../test; pwdсделает это. И я не согласен с тем, что это непоследовательно, вполне разумно, что shell поддерживает CWD как "состояние"без необходимости держать открытую файловую ручку в каталоге.
https://stackoverflow.com/questions/60008928/why-can-a-directory-be-removed-when-my-shell-is-using-that-directory/60009103#comment106138795_60009103
Это несовместимо с запретом размонтировать файловую систему, когда есть процесс, который сделал cdв FS.
root

02.02.2020 09:19:15

Чтобы ответить на ваш первый вопрос:

Это не ошибка, это то, как всегда работали системы Unix, включая Linux.

Есть даже какой-то хороший текст в спецификации POSIX:

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

А именно, некоторые реализации (например, Windows...) можно назвать это ошибкой, но большинство реализаций. а именно варианты Unix, не надо.

Способ реализации этого в файловой системе заключается в том, что процессы содержат ссылку на объект, представляющий каталог. Еще одна вещь, которая содержит такую ссылку, - это родительский каталог. git rebaseудалил последнюю ссылку, но первая остается. Даже если каталог создан заново, это новый объект файловой системы, в то время как ваша оболочка содержала ссылку на старый объект.

Вот почему cd ..и cd $(pwd)все еще работают - они повторно просматривают каталог и захватывают новую ссылку и освобождают старую ссылку.

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

Чтобы ответить на ваш второй вопрос:

Чтобы извлечь диск, необходимо размонтировать точку монтирования, и, как указано выше, процессы, которые вы находите с fuser, содержат ссылки на эту точку монтирования.

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

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

Ну, это на самом деле можно сделать с umount --lazy.

Закрыть X