【发布时间】:2017-11-18 11:39:15
【问题描述】:
我已经为 Windows 10 安装了 Ubuntu 组件。
在 Ubuntu 中,我安装了 tesseract。所以在 bash 中,我可以运行这个命令:
$ tesseract /mnt/c/Code/screenshot.png stdout
而且它有效。
在 PowerShell 中,我可以做到这一点,而且它也可以:
PS> bash -c "tesseract /mnt/c/Code/screenshot.png stdout"
无法从 Windows PowerShell 启动 Python 2.7.13 并尝试从中调用 bash。我一开始试过这个:
>>> from subprocess import check_output
>>> check_output(['bash', '-c', 'tesseract /mnt/c/Code/screenshot.png stdout'])
这给了我:WindowsError: [Error 2] The system cannot find the file specified。
如果我把它简化成这样:
>>> check_output(['bash'])
我得到同样的错误。
>>> check_output(['bash'], shell = True)
现在我得到:'bash' is not recognized as an internal or external command, operable program or batch file.
好的。对bash.exe 的位置进行了一些研究。我在C:\Windows\System32\bash.exe 找到了它。但这仍然不起作用:
>>> check_output([r'C:\Windows\System32\bash.exe'], shell = True)
但它只是把它吐出来:'C:\Windows\System32\bash.exe' is not recognized as an internal or external command, operable program or batch file.
这里发生了什么?在 Windows 10 的 PowerShell 上运行的 Python 实例中,如何调用 Windows 10 的 Ubuntu 组件安装的 bash 副本中的某些内容?
【问题讨论】:
-
您正在运行 32 位 Python,因此 System32 被重定向到没有 bash.exe 的 SysWOW64。使用 64 位 Python 或
"C:\Windows\SysNative\bash.exe"。 “SysNative”是为 32 位 WOW64 进程实现的虚拟目录,用于运行 64 位系统可执行文件。 -
@eryksun - 完美!谢谢!请将此添加为答案,以便我接受并投票。 (似乎是一个巨大的缺点,错误消息根本没有提到这一点......你只需要知道它正在重定向东西并且你需要使用
SysNative才能真正到达System32......)跨度> -
行为是documented,因此有人为构建一个应该在 64 位 Windows 中运行的 32 位应用程序而获得报酬应该考虑涉水阅读文档只是工作的一部分。对于志愿者和业余爱好者来说,在编写一行代码之前花费数小时阅读枯燥的文档是一种痛苦,这是可以理解的。
-
@eryksun - 我敢打赌,我公司里没有人知道这种行为(除了我,因为你刚刚告诉我。)这是一个模糊的事实,从来没有发生过在我十多年的编程生涯中。也许系统管理员之类的人会知道这一点。作为习惯了 macOS 的人,我最大的想法是“32 位与 64 位仍然是个问题吗?”
-
现有的 32 位程序应该可以不加修改地运行,而且很多都是硬编码的,比如直接从 System32 加载 DLL。它可以以不同的方式实现,但我不知道设计决策中的所有因素。我知道最终的结果是 WOW64 充满了鬼鬼祟祟的魔法,需要阅读文档以避免意外。
标签: python windows bash powershell subprocess