Вопрос или проблема
В .bashrc
у меня есть некоторая конфигурация для конкретных окружений, как это.
if [ "$(uname)" = 'Linux' ]; then
. "$HOME/.bash.d/ubuntu"
fi
if [ "$(uname)" = 'Darwin' ]; then
. "$HOME/.bash.d/osx"
fi
Чтобы узнать, находится ли текущее окружение под WSL, я использую файл /etc/wsl.conf
, который обычно существует только в WSL.
if [ -f "/etc/wsl.conf" ]; then
. "$HOME/.bash.d/wsl"
fi
Но, конечно, файл также может существовать и в других окружениях.
Как мне проверить, работает ли текущее окружение в WSL?
Нет “безошибочного” способа сделать это, поскольку каждый метод обнаружения может привести к ложным срабатываниям или ложным отрицаниям в определенных ситуациях. Тем не менее, если вы делаете это только для своих личных конфигурационных файлов, то, вероятно, у вас есть довольно хорошее представление о том, сработает ли тот или иной метод на вашей системе или нет.
Некоторые различные методы, со своими плюсами и минусами:
-
Наличие
/proc/sys/fs/binfmt_misc/WSLInterop
является довольно хорошим индикатором того, что вы находитесь в WSL. Этот может быть самым надежным методом, и именно его использует проект Snapd Ubuntu в качестве механизма обнаружения. Этот файл по умолчанию существует как в WSL1, так и в WSL2. Даже когда Interop отключен через/etc/wsl.conf
, этот файл все равно будет создан WSL при запуске.Предостережения: Конечно, запись
binfmt_misc
можно настроить с именемWSLInterop
, но это было бы крайне паталогично, что привело бы к ложному срабатыванию теста.Кроме того, возможно переопределить название Interop, как упоминается в моем ответе на Ask Ubuntu здесь. Это было бы необычным случаем, но мы использовали это, чтобы временно предотвратить обнаружение WSL Snapd, пока исправляли ошибку. Это создает ложное отрицание, конечно.
В войне эскалации, вы можете “испередить-упреждение”, произвев поиск
magic 4d5a
в этой директории, но это может быть немного слишком 😉 -
Как @MBehrens упоминает, по умолчанию название ядра в WSL содержит строку “Microsoft” (или “microsoft”, в зависимости от версии). Использование
uname -r
или/proc/version
) может быть использовано для обнаружения.Предостережения: Другие системы могут (я думаю о Azure) использовать ядро, собранное Microsoft, что может привести к ложному срабатыванию. И возможно собрать пользовательское ядро для WSL2 с другим именем, что приведет к ложному отрицанию.
-
Вы даже можете просто проверить переменную окружения
$WSL_DISTRO_NAME
. Эта переменная автоматически внедряется в окружение WSL.Предостережения: Вы всегда можете (паталогично) создать это имя переменной на любой системе, что приведет к ложным срабатываниям.
Что более важно, есть случаи, когда эта переменная не будет доступна, например, если вы
su - $USER
.
Конечно, есть и другие методы (например, проверьте, исполняется ли $(which powershell.exe)
), но вышеуказанные варианты должны дать вам представление о различных подходах.
Проверьте вывод команды
cat /proc/version
и
cat /proc/sys/kernel/osrelease
Например:
if [[ $(grep -i Microsoft /proc/version) ]]; then
echo "Bash работает в WSL"
fi
Если у вас включен systemd, вы можете попробовать
systemd-detect-virt
это должно вернуть
wsl
Хотя немного запоздало, но в WSL команда lscpu
показывает строку:
Hypervisor vendor: Windows Subsystem for Linux
Это происходит как для обычного пользователя, так и при использовании sudo su
.
WSL имеет свои собственные ядра – когда вы запускаете uname – будет показано специфическое для MS ядро, которое указывает на WSL2
uname -r
5.15.153.1-microsoft-standard-WSL2
Ответ или решение
Для проверки, работает ли среда в Windows Subsystem for Linux (WSL), можно использовать несколько методов в рамках оболочки bash. Каждая из этих техник имеет свои плюсы и минусы, и выбор метода может зависеть от ваших конкретных требований и сценариев использования. Рассмотрим наиболее распространенные и эффективные способы определения WSL.
1. Использование файла /proc/version
Одним из наиболее надёжных способов является проверка на наличие строки "Microsoft" в файле /proc/version
. Этот файл содержит информацию о версии ядра и окружении.
if grep -qi microsoft /proc/version; then
echo "Среда работает под WSL"
fi
2. Проверка по версии ядра с помощью uname
Вы также можете использовать команду uname -r
, которая выводит информацию о текущем ядре. В WSL версия ядра содержит строку "microsoft":
if [[ "$(uname -r)" == *"microsoft"* ]]; then
echo "Среда работает под WSL"
fi
3. Проверка наличия переменной окружения
Переменная окружения $WSL_DISTRO_NAME
автоматически вводится в окружение WSL. Это может быть простым способом проверки:
if [ -n "$WSL_DISTRO_NAME" ]; then
echo "Среда работает под WSL"
fi
4. Использование systemd-detect-virt
Если у вас включён systemd
, вы можете использовать команду systemd-detect-virt
. Эта команда должна вернуть "wsl", если вы работаете в WSL:
if [[ "$(systemd-detect-virt)" == "wsl" ]]; then
echo "Среда работает под WSL"
fi
5. Проверка с помощью lscpu
Команда lscpu
также может быть полезной. Она отображает информацию о архитектуре процессора, и если вы находитесь в WSL, вы увидите строку, указывающую на это:
if lscpu | grep -q "Hypervisor vendor: Windows Subsystem for Linux"; then
echo "Среда работает под WSL"
fi
6. Проверка наличия специфичных файлов
Как вы уже упомянули, файл /etc/wsl.conf
обычно существует только в WSL. Однако, как вы правильно заметили, это не самый надежный метод, поскольку его наличие может быть случайно или намеренно создано в других окружениях. Тем не менее, для полной проверки можно его добавить:
if [ -f "/etc/wsl.conf" ]; then
echo "Возможно, это WSL (но необходимо дополнительное подтверждение)"
fi
Заключение
Для наиболее надёжного определения среды WSL я рекомендую использовать комбинацию из вышеуказанных методов, например, проверку наличия строки "Microsoft" в /proc/version
в сочетании с проверкой наличия переменной $WSL_DISTRO_NAME
. Это позволит минимизировать риск ложных срабатываний.
Вот пример общего скрипта, который объединяет эти методы:
if grep -qi microsoft /proc/version || [[ "$(uname -r)" == *"microsoft"* ]] || [ -n "$WSL_DISTRO_NAME" ]; then
echo "Среда работает под WSL"
else
echo "Среда не WSL"
fi
Эти методы являются наиболее распространёнными и надёжными способами проверить, работает ли ваш скрипт в окружении WSL.