1

Is there a way how to preserve stdout and stderr order when subprocess module is used?

hello.c

#include <stdio.h>
void main()
{
   printf("o1 ");
   fprintf(stderr, "e1 ");
   printf("o2 ");
   fprintf(stderr, "e2 ");
   printf("o3 ");
   fprintf(stderr, "e3 ");
}

test.py

import subprocess

print ("Test 1")
sp = subprocess.Popen("hello", stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
output = str(sp.communicate()[0])
print(output)

print ("Test 2")
sp = subprocess.Popen("hello", stdout = subprocess.PIPE, stderr = subprocess.PIPE)
stdout, stderr = sp.communicate() 
print(stdout + stderr)

print ("Test 3")
print(subprocess.check_output("hello", stderr=subprocess.STDOUT))

Output:

hello
o1 e1 o2 e2 o3 e3

Test 1
o1 o2 o3 e1 e2 e3
Test 2
o1 o2 o3 e1 e2 e3
Test 3
o1 o2 o3 e1 e2 e3
Peter Petrik
  • 9,701
  • 5
  • 41
  • 65
  • may be you have to use string manuplation – 0o'-Varun-'o0 Apr 23 '15 at 09:08
  • Look at this answer: http://stackoverflow.com/a/11709034/34088 – Aaron Digulla Apr 23 '15 at 09:11
  • where is `hello` coming from? – Padraic Cunningham Apr 23 '15 at 09:19
  • @PadraicCunningham I have edited the question. That is compiled hello.c – Peter Petrik Apr 23 '15 at 09:27
  • @AaronDigulla Thanks, that helped. I was kind of hoping for some simple suprocess argument/function. – Peter Petrik Apr 23 '15 at 09:28
  • I am amazed that the last code runs. – Padraic Cunningham Apr 23 '15 at 09:38
  • 1
    @Peter, do you control the output here from the process? If so, setvbuf could be helpful. If not, then you'll have trouble: stderr is usually not buffered, whereas stdout is usually line-buffered for terminals and buffered otherwise. I'll note that when I try your code in a shell, I get e1 e2 e3 o1 o2 o3, as one would expect, unless I unset the stdout buffering first. And do you actually need stderr and stdout on the same lines, or are you interested in separate lines (in which case this is actually a duplicate, and not just mistakenly closed)? – cge Apr 23 '15 at 09:38
  • I have meant it in general, not just separate lines. But answer stackoverflow.com/a/11709034/34088 is usefull too. – Peter Petrik Apr 23 '15 at 09:47
  • If you can modify the output program, adding `setvbuf( stdout, NULL, _IONBF, 0 );` before any output will make your stdout unbuffered, and then (if, for test 3, you also ensure you have a 0 exit code by having int main and return 0) both your test 1 and test 3 will work as intended. – cge Apr 23 '15 at 09:57
  • I have just tried. It is not working, at least on Windows with VS2010. – Peter Petrik Apr 23 '15 at 10:04
  • Note that changing the output buffering is only an option for programs which don't emit a lot of output. Line buffering is expensive and will impact performance considerably. – Aaron Digulla Apr 23 '15 at 10:05

0 Answers0