Можно ли получить доступ к файлам из одной WSL 2 дистрибутив/образа в другом?

Вопрос или проблема

У меня есть несколько “установок” Ubuntu WSL 2 на моей системе Windows 10, и я хотел бы иметь возможность запускать инструменты, такие как rsync и diff, между ними. Можно ли монтировать/находить, где находятся файлы этих других копий, и выполнять на них команды Linux? Я не хочу копировать в эту область, просто хочу иметь возможность “копировать из нее”.

Для конкретизации у меня есть:

X:\WSL\U18.04_1 и X:\WSL\U18.04_2

И я могу зайти во вторую, сказав:

wsl -d X:\WSL\U18.04_2 -u myname

Это откроет оболочку bash в моем домашнем каталоге в образе U18.04_2. Теперь я хотел бы сделать следующее:

diff -rbitw /mnt/x/WSL/U18.04_1/home/myname /home/myname

Но, конечно, это не работает, потому что /mnt/x/WSL/U18.04 на самом деле не является файловой системой (насколько я могу судить).

Существует несколько способов достижения этого.

Вариант 1: записи в /etc/fstab в каждом дистрибутиве

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

В каждом дистрибутиве выполните следующую команду один раз:

echo "/ /mnt/wsl/instances/$WSL_DISTRO_NAME none defaults,bind,X-mount.mkdir 0 0" | sudo tee -a /etc/fstab

1 (Благодарность и спасибо @mtraceur за комментарий/предложение и последующую отредактированную команду. Упрощение кавычек всегда приветствуется!)

После завершения работы WSL-дистрибутива и перезапуска (для обработки /etc/fstab) ваш дистрибутив будет доступен под /mnt/wsl/instances/<distroname> из всех других дистрибутивов WSL2.

2 См. Вариант 1.5, если это не работает.

См. мой связанный ответ на Ask Ubuntu для деталей, почему это работает.

Вариант 1.5: обходной путь для /etc/fstab для последних выпусков WSL

В последних выпусках WSL (0.47.1 и новее, по-моему) проблема/изменение времени означает, что fstab обрабатывается и монтируется до того, как /mnt/wsl (файловая система tmpfs) будет замонтирована. Если вы используете последнюю версию WSL и обнаруживаете, что /mnt/wsl/ не содержит подкаталога instances, тогда:

sudo -e /etc/wsl.conf

Добавьте следующее:

[automount]
mountFsTab = false

[boot]
command = sleep 5; mount -a

Это должно подождать достаточно долго перед обработкой /etc/fstab, чтобы /mnt/wsl было замонтировано сначала WSL.

Если вы используете Systemd, вы также можете создать файл .mount для обхода проблемы. См. ответ @SteveMeierhofer для деталей.

Вариант 2: Используйте stdin/stdout wsl.exe

(Бонус #1: Этот метод работает и на WSL1)
(Бонус #2: Он не требует предварительной настройки)
(Бонус #3: Он будет работать, даже если второй дистрибутив еще не запущен. Опция 1 требует, чтобы дистрибутив был запущен заранее, чтобы он был доступен в /mnt/wsl.)

Для некоторых случаев использования вы можете просто использовать нормальную перенаправление ввода/вывода через команду wsl.exe для доступа к заданному файлу. Например:

wsl.exe -d otherinstance cat ~/myfile | diff myfile -

или

diff myfile <(wsl.exe -d otherinstance cat ~/myfile) # bash (вероятно, все posix)
diff myfile (wsl.exe -d otherinstance cat ~/myfile | psub) # fish

Это похоже на то, как вы можете выполнять те же операции на удаленном хосте через ssh. Вы можете даже отправить целые директории через канал, используя tar (или другими способами).

Это также не требует, чтобы второй дистрибутив был запущен заранее.

Вариант 3: ssh

Для редких случаев вы даже можете настроить ssh-серверы в каждой инстанции. Единственный случай, когда я должен сделать это – это Ansible, хотя rsync тоже может быть вариантом.

Обратите внимание, что настройка ssh на инстанциях WSL не столь проста, но, вероятно, проще, если вы получаете доступ к ним только через localhost. По крайней мере, вам понадобится отдельный номер порта для каждой инстанции. Рекомендую зарезервировать 22 для самого хоста Windows (возможно, используя Windows OpenSSH Server).

Вариант 4: Привязка монтирования в /mnt/wsl

Более старый вариант Варианта 1, оставленный здесь для истории.

Адаптировано из этого комментария на GitHub, вы должны быть в состоянии сделать следующее:

mkdir /mnt/wsl/otherinstance
wsl.exe -d otherinstance -u root mount --bind / /mnt/wsl/otherinstance/

Честно говоря, это немного пугает меня, потому что “otherinstance” завершается вскоре после выполнения команды (если он не был уже запущен где-то еще). Однако, монтирование кажется стабильным, вероятно, потому что (как уже упоминалось в комментариях к этому вопросу на GitHub) все “диски” доступны из подсистемы WSL2/Hyper-V; они не обязательно зависят от самой инстанции.

В любом случае, можно легко рассеять мои (возможно, необоснованные) опасения, просто запустив “otherinstance” вручную и выполняя mount --bind непосредственно из этой инстанции.

Если у вас есть недавний выпуск WSL из Microsoft Store, тогда можно использовать Systemd. Как только инстанция WSL запущена с Systemd, создайте файл монтирования, например:

/etc/systemd/system/mnt-wsl-instances-${WSL_DISTRO_NAME}.mount

[Unit]
Description=WSL Instances

[Mount]
What=/
Where=/mnt/wsl/instances/${WSL_DISTRO_NAME}
Type=none
Options=defaults,bind,X-mount.mkdir

[Install]
WantedBy=multi-user.target

И затем активируйте монтирование:

sudo systemctl daemon-reload

sudo systemctl enable mnt-wsl-instances-${WSL_DISTRO_NAME}.mount --now

Все файлы WSL доступны по адресу /mnt/wsl/instances.

Самый простой способ: это Проводник Windows.

  1. Откройте проводник Windows и получите доступ к “удаленному” адресу \\wsl$, вы увидите что-то вроде этого:
    пример результата
  2. Теперь щелкните правой кнопкой мыши по одному из них и выберите “Открыть в новом окне”
  3. Разместите их рядом и исследуйте/копируйте/вставляйте файлы по мере необходимости.

Вы можете копировать файлы из старого WSL в новый WSL через SSH и сохранять разрешения на файлы.
Пример:

Старый WSL:

sudo apt install ssh
sudo vi /etc/ssh/sshd_config   =>   port 22000
sudo service ssh restart

Новый WSL:

# ssh localhost:22000
rsync -av -e 'ssh -p 22000' localhost:src_old_machine_file dst_new_machine_file

Опираясь на ответ Стива, я обернул его в виде команды “все-в-одном”, которую вы можете просто вставить во все дистрибутивы WSL, с которыми вы хотите связать файловые системы. Она также включает исправления для дистрибутивов, содержащих дефисы, например, дистрибутивов Ubuntu.

Это протестировано на Ubuntu 20.04 и 24.04 с включенным systemd в обоих.

cat <<EOF | sudo tee /etc/systemd/system/mnt-wsl-instances-${WSL_DISTRO_NAME/-/}.mount
[Unit]
Description=WSL Instances

[Mount]
What=/
Where=/mnt/wsl/instances/${WSL_DISTRO_NAME/-/}
Type=none
Options=defaults,bind,X-mount.mkdir

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload

sudo systemctl enable mnt-wsl-instances-${WSL_DISTRO_NAME/-/}.mount --now

В качестве дополнения к Option 1 (1.5) @NotTheDr01ds, вы можете просто использовать одну единственную команду монтирования в wsl.conf:

[boot]
command = "mount --bind / /mnt/wsl/instances/$WSL_DISTRO_NAME/ -o x-mount.mkdir"

Команда загрузки всегда выполняется после автомонтирования wsl и выполняется только один раз – при старте инстанции wsl.


P.S. Существует сокращение -B для --bind и (в последних версиях) -m для -o x-mount.mkdir, так что это можно упрощенно записать как

[boot]
command = "mount -Bm / /mnt/wsl/instances/$WSL_DISTRO_NAME/"

P.P.S. Если у вас также есть другие команды запуска, просто объедините их в серию:

[boot]
command = "mount -Bm / /mnt/wsl/instances/$WSL_DISTRO_NAME/; service ssh start; ..."

.

Ответ или решение

В Windows Subsystem for Linux (WSL) версии 2 возникает довольно частый запрос на доступ к файлам из одной дистрибутивной среды WSL в другой. Это может быть необходимо для выполнения различных задач, таких как сравнение (diff) и синхронизация (rsync) данных между дистрибутивами. Давайте рассмотрим несколько возможных методов решения данной задачи, опираясь на теоретическую основу, примеры и практическое применение.

Теоретическая основа

WSL 2 предоставляет возможность использовать дистрибутивы Linux на ОС Windows, что делает работу с различными версиями Linux гибкой и интегрированной. Однако, поскольку каждый дистрибутив на WSL изолирован в своём относительно самостоятельном пространстве, доступ к информации между ними требует дополнительных шагов. Основной вызов заключается в том, чтобы обеспечить безопасный и эффективный метод доступа к файловым системам различных дистрибутивов из другой среды.

Примеры решения

  1. Редактирование /etc/fstab для монтирования файловых систем. Этот метод предполагает использование файла конфигурации fstab для автоматического монтирования файловой системы при запуске. После дополнительных изменений в конфигурации WSL можно сделать содержимое одного дистрибутива доступным в другом через стандартные точки монтирования Linux.

  2. Использование средств командной строки для доступа к файлам. С помощью команды wsl.exe можно пересылать stdout в другой WSL дистрибутив, что позволяет использовать команды, такие как cat, для переноса содержимого файлов из одной среды в другую без их непосредственного переноса на уровне файловой системы.

  3. Настройка SSH-серверов. Один из наиболее универсальных способов доступа к файловой системе — это настройка SSH в каждом дистрибутиве. Это позволяет использовать стандартные инструменты, такие как scp или rsync, для доступа и управления файлами удалённо в пределах одной машины.

  4. Использование монтирования через Systemd. Для пользователей, имеющих последнюю версию WSL с поддержкой Systemd, создание и настройка systemd услуг для автоматического монтирования файловых систем может стать устойчивым и легко поддерживаемым решением.

Практическое применение

  1. Настройка fstab. Чтобы использовать этот подход, выполните следующие команды для каждого дистрибутива:

    echo "/ /mnt/wsl/instances/$WSL_DISTRO_NAME none defaults,bind,X-mount.mkdir 0 0" | sudo tee -a /etc/fstab

    Перезапустите дистрибутив, чтобы изменения вступили в силу. Это позволит дистрибутиву монтироваться в заданную директорию при каждом запуске.

  2. Командная строка с wsl.exe. Чтобы автоматически получать доступ к файлам из другого дистрибутива, можно использовать подходы, схожие с SSH:

    wsl.exe -d otherinstance cat ~/myfile | diff myfile -

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

  3. SSH-сервер в WSL. Установите и настройте SSH:

    sudo apt install ssh
    sudo vi /etc/ssh/sshd_config  # Установите уникальный порт для каждого дистрибутива
    sudo service ssh restart

    Используйте rsync для копирования файлов, поддерживая их разрешения, через SSH.

  4. Systemd для монтирования. Активируйте поддержку Systemd и создайте файлы для автоматического монтирования:

    cat <<EOF | sudo tee /etc/systemd/system/mnt-wsl-instances-${WSL_DISTRO_NAME}.mount
    [Unit]
    Description=WSL Instances
    
    [Mount]
    What=/
    Where=/mnt/wsl/instances/${WSL_DISTRO_NAME}
    Type=none
    Options=defaults,bind,X-mount.mkdir
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    sudo systemctl daemon-reload
    sudo systemctl enable mnt-wsl-instances-${WSL_DISTRO_NAME}.mount --now

    Эти команды обеспечат автоматическое монтирование файловых систем при запуске сервиса.

Таким образом, доступ к файлам из одного WSL 2 дистрибутива в другой можно реализовать разнообразными способами, от простых клиентских подходов, реализуемых через командную строку, до более комплексных решений с использованием средств монтирования и SSH. Выбор метода зависит от ваших текущих задач и уровня комфорта с настройками системы.

Оцените материал
Добавить комментарий

Капча загружается...