0

I'm trying to run bash.exe (Bash on Ubuntu for Windows) as a build command for Sublime Text. However, bash.exe has a bug and does not support outputting its stdout to any pipe.

Question is this: how can I run a cmd line (i.e. "bash.exe -c ls") and capture the output without ever making bash.exe output into pipes on windows?

I'm open to using any languages or environment on Windows to make this tool.

Edit

I ran bashTest = subprocess.Popen(["bash.exe", "-c", "ls"]), stdout=subproccess.PIPE)

Which yielded:

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'

4
  • You can use a pipe like this: echo "hello world" | { read test; echo test=$test; } or even write a function like this: read_from_pipe() { read "$@" <&0; } Commented Sep 5, 2016 at 7:09
  • The problem is that any time code tries to print bash.exe's output to a pipe, as this github page says, the only information provided is some random error message. Pipes cannot be part of the process at all.
    – RaphaelM
    Commented Sep 5, 2016 at 7:17
  • post the error and your input please Commented Sep 5, 2016 at 7:19
  • [Comment moved to main question edit for clarity]
    – RaphaelM
    Commented Sep 5, 2016 at 7:20

3 Answers 3

1

This is currently not possible. There's a 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.

There are ways you could hack around it, however. One way would be to write a script which loops forever in a bash.exe console. When the script gets a signal, it runs Linux commands with the output piped to a file then signals that it is complete. Here's some pseudo code:

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

This does require keeping a bash.exe console always open with the script running, which is not ideal.

Another potential workaround, which was already mentioned, is to use ReadConsoleOutput.

0

You need to use the option shell=True in Popen() to have pipes work.

like this example dont need to split this command.

>>> import subprocess as sp    
>>> cmd = 'echo "test" | cat'
>>> process = sp.Popen(cmd,stdout=sp.PIPE,shell=True)
>>> output = process.communicate()[0]
>>> print output
test
4
  • Did not change anything, unfortunately. If you doubt the problem I am having, the github page I mentioned is very clear about the incompatibility. I am looking for some workaround to using pipes.
    – RaphaelM
    Commented Sep 5, 2016 at 7:34
  • you can also redirect to a subshell using process substitution: command > >(stdlog pipe) 2> >(stderr pipe) for example command 2> >(grep 'something') >/dev/null Commented Sep 5, 2016 at 7:45
  • (gnu.org/software/bash/manual/bash.html#Redirections)[this address also has info about redirections] Commented Sep 5, 2016 at 7:47
  • @khakishoiab: please do note that the question is NOT about the usual bash on Linux, Cygwin and so on, but about WSL. On the Windows side of WSL, "bash" is not the bash shell proper, it is a launcher that makes certain hocus-pocus resulting in the real bash starting in the "linux" environment, its stdin and stdout piped into the Windows console box. It's complicated,
    – ddbug
    Commented Sep 9, 2016 at 23:43
0

Your only realistic option, if you can't wait for a fix, would be to use ReadConsoleOutput and/or the related functions.

Not the answer you're looking for? Browse other questions tagged or ask your own question.