我如何从 WSL (Ubuntu) 运行 Windows 可执行文件 Bash
How can I run a Windows executable from WSL (Ubuntu) Bash
随着 2016 年夏季的 Windows 10 周年更新,运行 ubuntu 新 Windows Subsystem for Linux (WSL) 中的二进制文件,一个 "lightweight" 虚拟化子系统。
不幸的是,启动 C:\Windows\System32\bash.exe
,另一个 bash
ELF 二进制文件在 WSL 内部启动了一个进程,您无法从中逃脱!您只能启动其他 ELF 二进制文件。
那么如何从 Windows Bash 执行 *.exe
文件?[1]
中也提出了问题
原生解决方案
官方解决方案提供了 Windows 10 Insider Preview Update (14951) is based on the almost forgotten binfmt_msc Linux 启动二进制文件的功能。 binfmt_misc 的注册命令是这样的(其中 /init
是临时 binfmt_misc "interpreter" 对于 win-executables):
sudo echo ":WSLInterop:M::MZ::/init:" > /proc/sys/fs/binfmt_misc/register
然后 win-executable 将像常规程序一样启动:
$ export PATH=$PATH:/mnt/c/Windows/System32
$ notepad.exe
$ ipconfig.exe | grep IPv4 | cut -d: -f2
$ ls -la | findstr.exe foo.txt
$ cmd.exe /c dir
Not that any win-executable must reside in the windows (DrvFs) file-system - not on the Linux's file-system (VolFs) - in order to inherit a proper Windows working-directory.
cbwin替代方案
在您获得最新版本之前,项目 cbwin 提供了一种解决方法,方法是在 WSL 中安装 3 个新的 linux 命令:
wcmd
:通过cmd.exe
调用win-executable。
wrun
:用CreateProcess
同步调用win-executable,等死(不使用cmd.exe
)。
wstart
:启动分离(异步)命令(使用 cmd.exe
)。
要使用它们,您必须:
- 安装 cbwin:
- 一个新的
outbash.exe
将安装在您的常规 Windows 文件系统中(在您的 %PATH%
中的某处),加上
- WSL 文件系统中的 3 个 linux-命令。
- 使用此
outbash.exe
(无论您安装在何处)启动 WSL,而不是 C:\Windows\System32\bash.exe
!
- 在任何 win 可执行文件前加上这些命令之一,例如
wrun notepad
.
提示: 如果使用 wcmd
或 wrun
启动的可执行文件生成了任何子项,则这些子项仅在可执行文件保持活动状态时存在。
换句话说,尝试用wcmd
启动notepad.exe
是行不通的,因为notepad会在启动后被杀死——在这种情况下使用 wrun
(同步)或 wstart
(异步)。
在 Windows 10 Creators Update(内部版本 1703,2017 年 4 月)中,这是原生支持的。所以你现在可以 运行 Windows 来自 Linux...
的二进制文件
notepad.exe
或任何其他 .exe
(需要扩展名 needs being on your path,一些旧版本需要整个路径)
...反之亦然,使用以下其中一项:
bash.exe -c command_to_run
即:bash.exe -c ls
bash -c command_to_run
即:bash -c ls
wsl command_to_run
即:wsl "ls"
;或指定要使用的发行版 运行 使用:
ubuntu run ls
有关详细信息,请参阅上面的链接文章。
虽然命令行中的 运行 和 .exe
有效,但当 运行 从 PHP 通过 exec()
时,我无法让它工作.但是,添加 /init
确实有效。这是我在 Windows:
上安装的 GraphicsMagick 的工作 /usr/local/bin/convert
文件
#!/bin/sh
/init "$(ls /mnt/c/Program*/GraphicsMagick*/gm.exe|tail -1)" convert "$@"
我对此有点困惑。我添加了一个符号链接:
$ ls -l /c
lrwxrwxrwx 1 root root 5 Dec 3 10:24 /c -> mnt/c
现在 ls /c 给出与 ls /mnt/c
相同的结果
但是现在:
/c/Program\Files/Java/jdk1.8.0_211/bin/java.exe -version
==> 没有
但是:
/mnt/c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe -version
java version "1.8.0_211" Java(TM) SE Runtime Environment (build 1.8.0_211-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
其他 windows 可执行文件也会发生同样的事情。
WSL 有实现符号链接的错误吗?
为什么不直接使用
$ powershell.exe Start filename
Start
是 Windows 相当于大多数 linux 上的 xdg-open
或 macOS 上的 open
,这意味着“使用默认桌面应用程序打开”。我喜欢给它起个别名来打开。
随着 2016 年夏季的 Windows 10 周年更新,运行 ubuntu 新 Windows Subsystem for Linux (WSL) 中的二进制文件,一个 "lightweight" 虚拟化子系统。
不幸的是,启动 C:\Windows\System32\bash.exe
,另一个 bash
ELF 二进制文件在 WSL 内部启动了一个进程,您无法从中逃脱!您只能启动其他 ELF 二进制文件。
那么如何从 Windows Bash 执行 *.exe
文件?[1]
原生解决方案
官方解决方案提供了 Windows 10 Insider Preview Update (14951) is based on the almost forgotten binfmt_msc Linux 启动二进制文件的功能。 binfmt_misc 的注册命令是这样的(其中 /init
是临时 binfmt_misc "interpreter" 对于 win-executables):
sudo echo ":WSLInterop:M::MZ::/init:" > /proc/sys/fs/binfmt_misc/register
然后 win-executable 将像常规程序一样启动:
$ export PATH=$PATH:/mnt/c/Windows/System32
$ notepad.exe
$ ipconfig.exe | grep IPv4 | cut -d: -f2
$ ls -la | findstr.exe foo.txt
$ cmd.exe /c dir
Not that any win-executable must reside in the windows (DrvFs) file-system - not on the Linux's file-system (VolFs) - in order to inherit a proper Windows working-directory.
cbwin替代方案
在您获得最新版本之前,项目 cbwin 提供了一种解决方法,方法是在 WSL 中安装 3 个新的 linux 命令:
wcmd
:通过cmd.exe
调用win-executable。wrun
:用CreateProcess
同步调用win-executable,等死(不使用cmd.exe
)。wstart
:启动分离(异步)命令(使用cmd.exe
)。
要使用它们,您必须:
- 安装 cbwin:
- 一个新的
outbash.exe
将安装在您的常规 Windows 文件系统中(在您的%PATH%
中的某处),加上 - WSL 文件系统中的 3 个 linux-命令。
- 一个新的
- 使用此
outbash.exe
(无论您安装在何处)启动 WSL,而不是C:\Windows\System32\bash.exe
! - 在任何 win 可执行文件前加上这些命令之一,例如
wrun notepad
.
提示: 如果使用 wcmd
或 wrun
启动的可执行文件生成了任何子项,则这些子项仅在可执行文件保持活动状态时存在。
换句话说,尝试用wcmd
启动notepad.exe
是行不通的,因为notepad会在启动后被杀死——在这种情况下使用 wrun
(同步)或 wstart
(异步)。
在 Windows 10 Creators Update(内部版本 1703,2017 年 4 月)中,这是原生支持的。所以你现在可以 运行 Windows 来自 Linux...
的二进制文件notepad.exe
或任何其他 .exe
(需要扩展名 needs being on your path,一些旧版本需要整个路径)
...反之亦然,使用以下其中一项:
bash.exe -c command_to_run
即:bash.exe -c ls
bash -c command_to_run
即:bash -c ls
wsl command_to_run
即:wsl "ls"
;或指定要使用的发行版 运行 使用:ubuntu run ls
有关详细信息,请参阅上面的链接文章。
虽然命令行中的 运行 和 .exe
有效,但当 运行 从 PHP 通过 exec()
时,我无法让它工作.但是,添加 /init
确实有效。这是我在 Windows:
/usr/local/bin/convert
文件
#!/bin/sh
/init "$(ls /mnt/c/Program*/GraphicsMagick*/gm.exe|tail -1)" convert "$@"
我对此有点困惑。我添加了一个符号链接:
$ ls -l /c
lrwxrwxrwx 1 root root 5 Dec 3 10:24 /c -> mnt/c
现在 ls /c 给出与 ls /mnt/c
相同的结果但是现在: /c/Program\Files/Java/jdk1.8.0_211/bin/java.exe -version ==> 没有
但是:
/mnt/c/Program\ Files/Java/jdk1.8.0_211/bin/java.exe -version
java version "1.8.0_211" Java(TM) SE Runtime Environment (build 1.8.0_211-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
其他 windows 可执行文件也会发生同样的事情。 WSL 有实现符号链接的错误吗?
为什么不直接使用
$ powershell.exe Start filename
Start
是 Windows 相当于大多数 linux 上的 xdg-open
或 macOS 上的 open
,这意味着“使用默认桌面应用程序打开”。我喜欢给它起个别名来打开。