- Вопрос или проблема
- Вариант 1: записи в /etc/fstab в каждом дистрибутиве
- Вариант 1.5: обходной путь для /etc/fstab для последних выпусков WSL
- Вариант 2: Используйте stdin/stdout wsl.exe
- Вариант 3: ssh
- Вариант 4: Привязка монтирования в /mnt/wsl
- Ответ или решение
- Теоретическая основа
- Примеры решения
- Практическое применение
Вопрос или проблема
У меня есть несколько “установок” 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.
- Откройте проводник Windows и получите доступ к “удаленному” адресу
\\wsl$
, вы увидите что-то вроде этого:
пример результата - Теперь щелкните правой кнопкой мыши по одному из них и выберите “Открыть в новом окне”
- Разместите их рядом и исследуйте/копируйте/вставляйте файлы по мере необходимости.
Вы можете копировать файлы из старого 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 изолирован в своём относительно самостоятельном пространстве, доступ к информации между ними требует дополнительных шагов. Основной вызов заключается в том, чтобы обеспечить безопасный и эффективный метод доступа к файловым системам различных дистрибутивов из другой среды.
Примеры решения
-
Редактирование
/etc/fstab
для монтирования файловых систем. Этот метод предполагает использование файла конфигурации fstab для автоматического монтирования файловой системы при запуске. После дополнительных изменений в конфигурации WSL можно сделать содержимое одного дистрибутива доступным в другом через стандартные точки монтирования Linux. -
Использование средств командной строки для доступа к файлам. С помощью команды
wsl.exe
можно пересылать stdout в другой WSL дистрибутив, что позволяет использовать команды, такие какcat
, для переноса содержимого файлов из одной среды в другую без их непосредственного переноса на уровне файловой системы. -
Настройка SSH-серверов. Один из наиболее универсальных способов доступа к файловой системе — это настройка SSH в каждом дистрибутиве. Это позволяет использовать стандартные инструменты, такие как scp или rsync, для доступа и управления файлами удалённо в пределах одной машины.
-
Использование монтирования через Systemd. Для пользователей, имеющих последнюю версию WSL с поддержкой Systemd, создание и настройка systemd услуг для автоматического монтирования файловых систем может стать устойчивым и легко поддерживаемым решением.
Практическое применение
-
Настройка fstab. Чтобы использовать этот подход, выполните следующие команды для каждого дистрибутива:
echo "/ /mnt/wsl/instances/$WSL_DISTRO_NAME none defaults,bind,X-mount.mkdir 0 0" | sudo tee -a /etc/fstab
Перезапустите дистрибутив, чтобы изменения вступили в силу. Это позволит дистрибутиву монтироваться в заданную директорию при каждом запуске.
-
Командная строка с wsl.exe. Чтобы автоматически получать доступ к файлам из другого дистрибутива, можно использовать подходы, схожие с SSH:
wsl.exe -d otherinstance cat ~/myfile | diff myfile -
Это позволит считывать и сравнивать файлы через командную строку, минимизируя накладные расходы на настройку системы.
-
SSH-сервер в WSL. Установите и настройте SSH:
sudo apt install ssh sudo vi /etc/ssh/sshd_config # Установите уникальный порт для каждого дистрибутива sudo service ssh restart
Используйте
rsync
для копирования файлов, поддерживая их разрешения, через SSH. -
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. Выбор метода зависит от ваших текущих задач и уровня комфорта с настройками системы.