我有一个程序可以从另一个程序中获取输出,该程序在 linux 的新 Windows 子系统上运行。我已经编写了一个从 windows 系统运行的 python 程序,但将使用 python 子进程模块执行 linux 程序。如果这令人困惑,请参阅下面的示例。
但是,当我这样做时,我发现当通过 python 子进程调用时,windows 找不到 bash 程序。
Windows 中命令行或 powershell 的示例:
C:\>bash -c "echo hello world!"
hello world!
C:\>python
Python 2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess as s
>>> s.call('bash -c "echo hello world"'.split())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\Python27-32\lib\subprocess.py", line 524, in call
return Popen(*popenargs, **kwargs).wait()
File "c:\Python27-32\lib\subprocess.py", line 711, in __init__
errread, errwrite)
File "c:\Python27-32\lib\subprocess.py", line 948, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
>>> s.call('bash -c "echo hello world"'.split(),shell=True)
'bash' is not recognized as an internal or external command,
operable program or batch file.
1
我想也许它没有以某种方式加载我的路径设置,所以我输入了 bash 程序的完整地址。
>>> s.call(b,shell=True)
'C:\Windows\System32\bash.exe' is not recognized as an internal or external command,
operable program or batch file.
1
编辑:我意识到我的命令可能会出现问题,因为 o 在空间上 split 并且“echo hello world”是一个参数,但是用 bash -c ls 尝试同样的事情也会给出同样的错误
最佳答案
对于在 WOW64 子系统中运行的 32 位程序,“System32”目录 gets redirected到“SysWOW64”。 WSL bash.exe 加载程序作为 64 位可执行文件分发,因此您需要从 32 位 Python 使用虚拟“SysNative”目录。例如:
import os
import platform
import subprocess
is32bit = (platform.architecture()[0] == '32bit')
system32 = os.path.join(os.environ['SystemRoot'],
'SysNative' if is32bit else 'System32')
bash = os.path.join(system32, 'bash.exe')
subprocess.check_call('"%s" -c "echo \'hello world\'"' % bash)
请注意,目前 Windows 管道未桥接至 WSL 管道,因此如果您尝试使用 stdout=PIPE 或 subprocess.check_output,WSL bash 加载程序将失败.您可以通过 ReadConsoleOutputCharacter 直接读取控制台输出(例如,参见 this answer )。或者,更简单地说,您可以将输出重定向到一个临时文件,将临时文件的路径转换为 WSL 路径。例如:
import tempfile
def wintolin(path):
path = os.path.abspath(path)
if path[1:2] == ':':
drive = path[:1].lower()
return '/mnt/' + drive + path[2:].replace('\\', '/')
cmd = '"%s" -c "echo \'hello world\' > \'%s\'"'
with tempfile.NamedTemporaryFile(mode='r', encoding='utf-8') as f:
subprocess.check_call(cmd % (bash, wintolin(f.name)))
out = f.read()
编辑:从 Windows build 14951 开始,您应该能够使用 stdout=PIPE。请参阅 WSL 博客文章 Windows and Ubuntu Interoperability .
关于python subprocess.call() 找不到 Windows Bash.exe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39812882/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R
我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions
我已经看到了一些其他的问题,尝试了他们的建议,但没有一个对我有用。我已经使用Rails大约一年了,刚刚开始一个新的Rails项目,突然遇到了问题。我卸载并尝试重新安装所有Ruby和Rails。Ruby很好,但Rails不行。当我输入railss时,我得到了can'tfindgemrailties。我当前的Ruby版本是ruby2.2.2p95(2015-04-13修订版50295)[x86_64-darwin15],尽管我一直在尝试通过rbenv设置ruby2.3.0。如果我尝试rails-v查看我正在运行的版本,我会得到同样的错误。我使用的是MacOSXElCapitan版本10
我花了几天时间尝试安装ruby1.9.2并让它与gems一起工作:-/我最终放弃了我的MacOSX10.6机器,下面是我的Ubuntu机器上的当前状态。任何建议将不胜感激!#rubytest.rb:29:in`require':nosuchfiletoload--mongo(LoadError)from:29:in`require'fromtest.rb:1:in`'#cattest.rbrequire'mongo'db=Mongo::Connection.new.db("mydb")#gemwhichmongo/usr/local/rvm/gems/ruby-1.9.2-p0/g
Ocra无法处理需要“tk”的应用程序require'tk'puts'nope'用奥克拉http://github.com/larsch/ocra不起作用(如链接中的一个问题所述)问题:https://github.com/larsch/ocra/issues/29(Ocra是1.9的"new"rubyscript2exe,本质上它用于将rb脚本部署为可执行文件)唯一的问题似乎是缺少tcl的DLL文件我不认为这是一个问题据我所知,问题是缺少tk的DLL文件如果它们是已知的,则可以在执行ocra时将它们包括在内有没有办法知道tk工作所需的DLL依赖项? 最佳答
我正在尝试获得良好的Ruby编码风格。为防止意外调用具有相同名称的局部变量,我总是在适当的地方使用self.。但是现在我偶然发现了这个:classMyClass上面的代码导致错误privatemethodsanitize_namecalled但是当删除self.并仅使用sanitize_name时,它会起作用。这是为什么? 最佳答案 发生这种情况是因为无法使用显式接收器调用私有(private)方法,并且说self.sanitize_name是显式指定应该接收sanitize_name的对象(self),而不是依赖于隐式接收器(也是
我正在尝试以一种更类似于普通RubyGem结构的方式构建我的Sinatra应用程序。我有以下文件树:.├──app.rb├──config.ru├──Gemfile├──Gemfile.lock├──helpers│ ├──dbconfig.rb│ ├──functions.rb│ └──init.rb├──hidden│ └──Rakefile├──lib│ ├──admin.rb│ ├──api.rb│ ├──indexer.rb│ ├──init.rb│ └──magnet.rb├──models│ ├──init.rb│ ├──invite.rb│ ├─