Linux – I edited a Linux file with a Windows program while using the Windows Subsystem for Linux, and now I can’t access it any more

windows-subsystem-for-linux

I'm using Bash on Ubuntu on Windows or another Linux distribution within the Windows Subsystem for Linux and I've edited a Linux file inside the lxss directory with a Windows editor.

Now whenever I or a program try to access it from Linux, I get an error "input/output error", or the file just disappears completely even though I can see it's definitely there in File Explorer.

cat abc
cat: abc: Input/output error

Why has this happened? What can I do to fix it? How can I avoid it in future?

Best Answer

Why has this happened?

Because conventional Unix filesystems work differently than Windows filesystems, WSL stores extra information about Linux-specific properties of files in the extended attributes of the Windows files used to represent them. Ordinary Windows programs don't know about these attributes and won't preserve them when you edit the file. Important information about the file is lost when that happens.

When WSL tries to read a file, and it can't find the attributes it expects, an error is reported, just like what would happen if a native filesystem were corrupted. If it never sees the attributes on a file in the first place, that file is just treated as non-existent and won't show up in file listings.

The official WSL advice is

DO NOT, under ANY circumstances, create and/or modify Linux files using Windows apps, tools, scripts, consoles, etc.

Creating/changing Linux files from Windows will likely result in data corruption and/or damage your Linux environment requiring you to uninstall & reinstall your distro!

for this reason (but bigger, and redder, and with more underlines). "Linux files" means anything inside your lxss directory. You can modify regular Windows files from inside Linux through the /mnt/c/... DrvFS filesystem, but not the reverse.

However, the 1903 Windows 10 release introduces a new mechanism that does allow files to be edited safely from Windows as long as you go about it the right way. That doesn't help to fix the problem of already-corrupted files, but it can avoid it in future.

What can I do to fix it?

If you've already edited a file and now you can't access it, it's still possible to read the contents from Windows itself and to restore the file that way.

To do that, you'll need to:

  1. Navigate back into the location within the AppData\Local\lxss directory that the file is in using File Explorer and move the file out to somewhere else on your drive, like your desktop.
  2. Restart WSL after that to clear its internal cache, which you can do just by closing all your terminals and opening a new one. If you have background server processes running, you will also need to stop those.
  3. Within Linux again, go to the original location of the corrupted file. It won't show up at all now if you've successfully moved the file out of the way. Run ls to check.
  4. Check the file you moved out: run

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

    to see the original contents of the file.

  5. If everything's worked so far, you can now copy that file back into the place you expected it to be:

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

    The cp command will cause WSL to restore the necessary hidden attributes on the file.

These instructions will work for regular data files, but if it's an important operating system file, you may need to reinstall entirely. For many non-critical programs, deleting the corrupted file from Windows and reinstalling the program using the package manager will be sufficient. You won't be able to delete the file from inside Linux once it's been corrupted.

How can I avoid this in future?

Never manipulate any files within the lxss directory from Windows. Instead:

  • If you have a file you want to access from both Windows and Linux, store it outside the lxss directory, anywhere else on your Windows system. You can open Windows files from Linux using the automatic DrvFS interoperability: the /mnt/c directory contains all of the files from your C: drive, and they can be read and written from Linux.

  • Starting in the 1903 Windows release (March 2019), WSL includes a special file server that makes your files available to all Windows applications. If you run

    explorer.exe .
    

    then File Explorer will open up showing the current Linux directory - you can copy files in or out of that window, or edit them with any application. The directory path will be something like \\wsl$\Ubuntu\var\www: the \\wsl$\ part sends file access through an alternative, safe, path.

    If you're able, this will be the best path forward (or sometimes the point above). For older releases, read on.

  • If there's a file you need to be in a specific place, like a configuration file, and you want to edit it from Windows, you can make a symbolic link from inside Linux to the file or directory's real location:

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

    This will work as long as the file doesn't need to have any specific permissions or attributes in Linux (as an executable or an SSH key would).

  • Alternatively, and perhaps better, edit your Linux files using a Linux editor within the terminal. nano, vim, and emacs are all readily available and work well under WSL, though they all have their quirks.

  • If you must edit a file with a Windows program, you don't have a recent-enough Windows version, and you can't make it a symlink, make a copy elsewhere to edit and copy it back in from /mnt/c afterwards, just like the fix above, or use version control to synchronise your edits across multiple locations.

From some experimentation, ordinary Notepad does seem to preserve the necessary attributes, but it doesn't understand Unix line endings so you're likely to corrupt the contents yourself, and I wouldn't rely on that behaviour in any case. Because this is an explicitly unsupported and undocumented operation it's unlikely that any Windows-based editor will be reliable.

Related Question