通过pipe()C调用与python交互的问题

时间:2019-04-04 21:24:03

标签: c linux pipe

我正在尝试为Linux编写一个C程序,它将能够通过pipe()调用与其他程序进行交互。以下代码不起作用,但是如果我将“ / usr / bin / python”更改为“ / bin / cat”(我的意思是,该行已打印出来),则完全相同。

#include <unistd.h>
#include <sys/prctl.h>
#include <signal.h>

int main()
{
        int inpipe[2], outpipe[2], pid, in_bytes;
        char *cmd[] = {"python", (char *) NULL}, buff[1024];
        pipe(inpipe);
        pipe(outpipe);

        pid = fork();
        if (pid == 0)
        {
                dup2(inpipe[1], 1);
                dup2(inpipe[1], 2);
                dup2(outpipe[0], 0);

                prctl(PR_SET_PDEATHSIG, SIGTERM);

                execve("/usr/bin/python", cmd, NULL);
        }
        close(inpipe[1]);
        close(outpipe[0]);

        write(outpipe[1], "print \"lol\"\n", 12);
        in_bytes = read(inpipe[0], buff, 1024);
        write(1, buff, in_bytes);

        close(inpipe[0]);
        close(outpipe[1]);
        return 0;
}

1 个答案:

答案 0 :(得分:0)

问题在于,当输入为tty时,python的默认行为仅类似于REPL。没有tty,就只是REP:

# Hangs until the pipe is closed with Ctrl+D
{ echo 'print "lol"'; cat; } | python

根据您要执行的操作,您有多种选择。其中两个包括:

  1. 运行python -i以获得REPL(char *cmd[] = {"python", "-i", (char *) NULL})。这将显示所有交互式提示等,因此您必须阅读更多数据。

  2. 关闭管道,以便Python知道脚本已完成。这将使其执行。

以下是您的代码,适合执行此操作:

#include <unistd.h>
#include <sys/prctl.h>
#include <signal.h>

int main()
{
        int inpipe[2], outpipe[2], pid, in_bytes;
        char *cmd[] = {"python", (char *) NULL}, buff[1024];
        pipe(inpipe);
        pipe(outpipe);

        pid = fork();
        if (pid == 0)
        {
                dup2(inpipe[1], 1);
                dup2(inpipe[1], 2);
                dup2(outpipe[0], 0);
                close(outpipe[0]);
                close(outpipe[1]);

                prctl(PR_SET_PDEATHSIG, SIGTERM);

                execve("/usr/bin/python", cmd, NULL);
        }
        close(inpipe[1]);
        close(outpipe[0]);

        write(outpipe[1], "print \"lol\"\n", 12);
        close(outpipe[1]);
        in_bytes = read(inpipe[0], buff, 1024);
        write(1, buff, in_bytes);

        close(inpipe[0]);
        close(outpipe[1]);
        return 0;
}