При некоторых обстоятельствах rm
Команда в Git-Bash удаляет файлы, которые нельзя удалить в проводнике, командной строке cmd, PowerShell или с помощью стандартных вызовов библиотеки C ++.
Зачем?
Это сбивает с толку меня, потому что я знаю, что здесь нет никакой магии, и я предполагаю, что все они используют один и тот же Win32 API.
Например, у меня есть снимки базы данных, которые остаются открытыми и не могут быть удалены с помощью других описанных методов, но были успешно удалены Git-Bash rm
:
Удалить обозреватель: «Действие не может быть завершено, потому что файл открыт».
CMD: del <path>
: «В доступе отказано»
PS: Remove-Item -Force -Path <path>
: «Невозможно удалить элемент. Доступ к пути запрещен.»
C ++ remove()
: возвращает -1
C ++ unlink()
: возвращает -1
C ++ _unlink()
: возвращает -1
ГИТ-Баш rm <path>
: успех
Выше может быть выполнено повторно для разных файлов.
Есть другие заблокированные файлы, которые git-bash rm
удаляет также успешно (я использовал это в прошлом, не недавно, и у меня нет других конкретных примеров).
Однако это не всегда работает: в тестовом приложении я открыл текстовый файл, используя fopen()
и ни один из методов, включая Git-Bash rm
, может успешно удалить его.
Итак, как работает Git-Bash rm?
Я смог выяснить, как это работает.
Интересно, что я использовал утилиту strace в Git-Bash. rm
команда.
Оказывается, что Git Bash использует CygWin, а процедура удаления находится в Файл CygWin syscalls.cc который пытается удалить файл несколькими различными способами.
В конце концов он пытается переместить файл в корзину, где удаляет заблокированный файл, открывая его с помощью вызова драйвера Windows NtOpenFile () с флагом FILE_DELETE_ON_CLOSE, а затем закрывая его с помощью NtClose ().
Не уверен, что было бы правильно скопировать код CygWin в ответ здесь, но подробности обо всем вышеупомянутом можно найти в предоставленной ссылке.
Других решений пока нет …