为什么会发生这种情况?

为什么会发生这种情况?

我在用着Windows 上 Ubuntu 上的 Bash或其他 Linux 发行版Linux 的 Windows 子系统lxss我已经使用 Windows 编辑器编辑了目录中的 Linux 文件。

现在,每当我或程序尝试从 Linux 访问它时,我都会收到错误“输入/输出错误”,或者文件完全消失,即使我可以看到它肯定存在于文件资源管理器中。

cat abc
cat: abc: Input/output error

为什么会发生这种情况?我能做什么来修复它?今后我该如何避免呢?

答案1

为什么会发生这种情况?

由于传统 Unix 文件系统的工作方式与 Windows 文件系统不同,WSL在扩展属性中存储有关 Linux 特定文件属性的额外信息用于表示它们的 Windows 文件的数量。普通的 Windows 程序不知道这些属性,并且在您编辑文件时不会保留它们。发生这种情况时,有关文件的重要信息就会丢失。

当 WSL 尝试读取文件但找不到所需的属性时,会报告错误,就像本机文件系统损坏时会发生的情况一样。如果它一开始就看不到文件的属性,则该文件将被视为不存在,并且不会显示在文件列表中。

WSL 官方建议

不要,在任何情况下、使用 Windows 应用程序、工具、脚本、控制台等创建和/或修改 Linux 文件。

从 Windows 创建/更改 Linux 文件可能会导致数据损坏和/或损坏您的 Linux 环境,需要您卸载并重新安装发行版!

出于这个原因(但更大,更红,并且有更多下划线)。 “Linux 文件”是指lxss目录中的任何内容。您可以通过以下命令从 Linux 内部修改常规 Windows 文件/mnt/c/...DrvFS 文件系统,但反之则不然。

然而,1903 年的 Windows 10 版本引入了一种新机制,允许从 Windows 安全地编辑文件只要你以正确的方式去做。这无助于解决已损坏文件的问题,但可以在将来避免这种情况。

我能做什么来修复它?

如果您已经编辑过文件但现在无法访问它,仍然可以从 Windows 本身读取内容并以这种方式恢复文件。

为此,您需要:

  1. 使用文件资源管理器导航回到文件所在AppData\Local\lxss目录中的位置,并将文件移至驱动器上的其他位置,例如桌面。
  2. 之后重新启动 WSL 以清除其内部缓存,只需关闭所有终端并打开一个新终端即可完成此操作。如果您有后台服务器进程正在运行,您还需要停止它们。
  3. 再次在 Linux 中,转到损坏文件的原始位置。如果您已成功将文件移开,它现在根本不会显示。跑去ls检查一下。
  4. 检查你移出的文件:运行

    cat /mnt/c/Users/.../Desktop/abc
    

    查看文件的原始内容。

  5. 如果到目前为止一切正常,您现在可以将该文件复制回您期望的位置:

    cp /mnt/c/Users/.../Desktop/abc ~/alphabet/abc
    

    cp命令将导致 WSL 恢复文件上必要的隐藏属性。

这些说明适用于常规数据文件,但是如果它是重要的操作系统文件,您可能需要完全重新安装。对于许多非关键程序,从 Windows 中删除损坏的文件并使用包管理器重新安装程序就足够了。一旦文件损坏,您将无法从 Linux 内部删除该文件。

今后我该如何避免这种情况?

lxss切勿从 Windows操作该目录中的任何文件。反而:

  • 如果您想从 Windows 和 Linux 访问某个文件,请将其存储外部目录lxss,Windows 系统上的任何其他位置。您可以使用以下命令从 Linux 打开 Windows 文件自动 DrvFS 互操作性:该/mnt/c目录包含 C: 驱动器中的所有文件,并且可以从 Linux 中读取和写入它们。

  • 从 1903 Windows 版本开始(2019 年 3 月),WSL包括一个特殊的文件服务器,使您的文件可用到所有 Windows 应用程序。如果你跑

    explorer.exe .
    

    然后文件资源管理器将打开,显示当前的 Linux 目录 - 您可以将文件复制到该窗口中或从该窗口中复制出来,或使用任何应用程序编辑它们。目录路径类似于\\wsl$\Ubuntu\var\www:该\\wsl$\部分通过替代的安全路径发送文件访问。

    如果你有能力的话这将是最好的前进道路(或者有时是上面的一点)。对于较旧的版本,请继续阅读。

  • 如果您需要将某个文件放在特定位置(例如配置文件),并且您想从 Windows 中编辑它,则可以从 Linux 内部创建一个到该文件或目录的真实位置的符号链接:

    ln -s /mnt/c/.../abc ~/.config/xyz/abc
    

    只要该文件在 Linux 中不需要具有任何特定权限或属性(如可执行文件或 SSH 密钥),就可以使用此方法。

  • 或者,也许更好的是,在终端中使用 Linux 编辑器编辑 Linux 文件。nanovim、 和emacs都随时可用并且在 WSL 下运行良好,尽管它们都有自己的怪癖。

  • 如果您必须使用 Windows 程序编辑文件,则您没有足够新的 Windows 版本,并且无法将其设置为符号链接,在其他地方创建一个副本以进行编辑,然后将其复制回来/mnt/c,就像修复上述问题,或使用版本控制在多个位置同步您的编辑。

从一些实验来看,普通记事本似乎确实保留了必要的属性,但它不理解 Unix 行结尾,因此您可能会自己损坏内容,并且在任何情况下我都不会依赖这种行为。由于这是明确不受支持且未记录的操作,因此任何基于 Windows 的编辑器都不可能可靠。

相关内容