【问题标题】:How does Git-Bash for Windows 'rm' work?Windows 'rm' 的 Git-Bash 是如何工作的?
【发布时间】:2018-07-01 18:42:29
【问题描述】:

在某些情况下,Git-Bash 中的rm 命令会删除无法在资源管理器、cmd 提示符、PowerShell 或使用 C++ 标准库调用中删除的文件。

为什么?

这让我感到困惑,因为我知道这里没有魔法,我假设它们都使用相同的 Win32 API。

例如,我有数据库快照保持打开状态,无法使用描述的其他方法删除,但被 Git-Bash rm 成功删除:

Explorer 删除:“该操作无法完成,因为文件已打开。”

cmd: del <path> : "访问被拒绝"

PS:Remove-Item -Force -Path <path>:“无法删除项目。访问路径被拒绝。”

C++ remove():返回 -1

C++ unlink():返回 -1

C++ _unlink():返回 -1

git-bash rm <path> : 成功

以上可以对不同的文件重复执行。

还有其他被 git-bash rm 成功删除的锁定文件(我过去用过,最近没用过,也没有其他具体例子)。

但它并不总是有效:在测试应用程序中,我使用 fopen() 打开了一个文本文件,但包括 Git-Bash rm 在内的任何方法都无法成功删除它。

那么,Git-Bash rm 是如何工作的呢?

【问题讨论】:

  • 我不确定 mingw 是否总是考虑 Windows 锁定状态:stackoverflow.com/a/39159518/6309
  • 可能是因为文件被git或者git-bash相关的东西锁定了?
  • 我认为 git-bash 本身正在锁定文件
  • 在我看到的情况下,git bash 没有锁定文件。特别是在提供的数据库示例中,快照被数据库进程锁定,当以不拥有数据库进程的管理员用户身份登录时,我可以从进程中“从下方”删除快照。
  • @vonc 对:我只能假设 git-bash "rm" 忽略了其他应用程序没有的权限或锁定检查。但是怎么做?我查看了 mingw 和 git-bash 存储库,但找不到“rm”的实现,甚至对 remove()、unlink() 和 _unlink() 的 win32 API 调用也不起作用。 ..

标签: c++ powershell git-bash


【解决方案1】:

我能够弄清楚这是如何工作的。

有趣的是,我在它的 rm 命令上使用了 Git-Bash 的 strace 实用程序。

事实证明,Git Bash 使用 CygWin,删除例程位于 CygWin syscalls.cc file 中,它尝试以几种不同的方式删除文件。

最终它会尝试将文件移动到回收站,在回收站中,它通过使用带有 FILE_DELETE_ON_CLOSE 标志的 Windows 驱动程序调用 NtOpenFile() 打开锁定的文件,然后使用 NtClose() 将其关闭。

不确定将 CygWin 的代码复制到此处的响应中是否合适,但可以在提供的链接中找到上述所有内容的详细信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-12
    • 2012-11-20
    • 2017-08-23
    • 1970-01-01
    • 2015-03-14
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多