简体   繁体   中英

Catch the output of child process' child process by subprocess module

I'm using Popen.communicate to test students' programs. I found an annoying fact, that this API might not be able to catch output of child process's child process.

For example, one student wrote some code like this

    if ((pid = fork()) == 0)
    {
        pwd(cwd);
        exit(0);
    }
    else
    {
        int ReturnCode;
        while (pid != wait(&ReturnCode))
        {
            ;
        }
    }

And pwd() simply prints the current directory

void pwd(const char *cwd)
{
    //printf("Current working directory is:\n");
    printf("%s\n", cwd);
}

My testing script simply couldn't get any output by using Popen.communicate. As programs that do not use multiprocess could pass my test script. I guess the only reason of the problem would be Popen.communicate some how couldn't get the output of a child process's child process.

Is there any walk around for this?

Edit:

This is my testing script

cd_command = '''cd /etc
pwd
cd /var
pwd
'''
def test_cd_pwd(self):
    # self.sh is the process that we are testing.
    self.out, self.err = self.sh.communicate(self.cd_command)
    self.assert_(self.out = "/etc\n/var\n")

I couldn't reproduce this here; the following worked for me:

guilty.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    int pid;
    if ((pid = fork()) == 0)
    {
        printf("Hello from child.\n");
        exit(0);
    }
    else
    {
        int ReturnCode;
        while (pid != wait(&ReturnCode))
        {
            ;
        }
        printf("Goodbye from parent.\n");
    }
}

test.py:

#!/usr/bin/python

from subprocess import Popen, PIPE

proc = Popen(['./a.out'], stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
print "out:", out
print "err:", err

output of ./test.py :

out: Hello from child.
Goodbye from parent.

err: 

I also tried:

  • printing without newlines in guilty.c
  • running Popen() with shell=True

In all cases, out contained the output of both processes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM