不使用管道从子进程读取输出

Read output from subprocess without using pipes

我正在尝试 运行 bash.exe(Ubuntu 上的 Bash for Windows)作为 Sublime Text 的构建命令。但是,bash.exe 有一个错误,不支持将其标准输出输出到任何管道。

问题是:我如何 运行 命令行(即“bash.exe -c ls”)并捕获输出,而无需将 bash.exe 输出到 windows?

我愿意在 Windows 上使用任何语言或环境来制作此工具。

编辑

我运行 bashTest = subprocess.Popen(["bash.exe", "-c", "ls"]), stdout=subproccess.PIPE)

产生了:

bashTest.communicate()[0] b'E\x00r\x00r\x00o\x00r\x00:\x00\x000\x00x\x008\x000\x000\x007\x000\x000\x005\x007\x00\r\x00\r\x00\n\x00'

您需要使用选项 shell=True in Popen() 让管道工作。

像这个例子不需要拆分这个命令。

>>> import subprocess as sp    
>>> cmd = 'echo "test" | cat'
>>> process = sp.Popen(cmd,stdout=sp.PIPE,shell=True)
>>> output = process.communicate()[0]
>>> print output
test

如果您等不及修复,您唯一现实的选择是使用 ReadConsoleOutput and/or 相关函数。

这目前是不可能的。有一个 github issue about it which was closed as a known limitation. If you want to increase awareness of it, I see 2 related User Voice ideas: Allow Windows programs to spawn Bash and Allow native Win32 applications to launch Linux tools/commands.

但是,您可以通过多种方式破解它。一种方法是编写一个在 bash.exe 控制台中永远循环的脚本。当脚本收到信号时,它会运行 Linux 命令并将输出通过管道传输到文件,然后发出完成信号。这是一些伪代码:

Linux:

while true
  while not exists /mnt/c/dobuild
    sleep 1
  end
  gcc foo.c > /mnt/c/build.log
  rm /mnt/c/dobuild
end

Windows:

touch C:\dobuild
while exists C:\dobuild
  sleep 1
end
cat C:\build.log

这确实需要保持 bash.exe 控制台始终使用脚本 运行 打开,这并不理想。

已经提到的另一个可能的解决方法是使用 ReadConsoleOutput.