C-exec未输出到管道中

C-exec未输出到管道中,c,exec,pipe,stdout,stdin,C,Exec,Pipe,Stdout,Stdin,我正在制作一个程序,它最终将能够(理论上)为传递给它的任何shell命令工作。我的问题是,运行的exec不会将其输出放入管道中,而在运行时,初始调用似乎会进入管道中?我试着先冲洗一下标准液,但不起作用。感谢您的帮助 int main(int argc, char *argv[]) { int i=0, pid; int dataPipe[2]; pipe(dataPipe); char *newArgs[5] = {"/bin/sh", "-c", "ls",

我正在制作一个程序,它最终将能够(理论上)为传递给它的任何shell命令工作。我的问题是,运行的exec不会将其输出放入管道中,而在运行时,初始调用似乎会进入管道中?我试着先冲洗一下标准液,但不起作用。感谢您的帮助

int main(int argc, char *argv[]) {

    int i=0, pid;
    int dataPipe[2];
    pipe(dataPipe);

    char *newArgs[5] = {"/bin/sh", "-c", "ls", "-a", NULL};

    if ((pid = fork()) < 0) {

        printf("Error: could not fork!");
        exit(2);
    }

    else if (pid == 0) {

        close(dataPipe[0]);
        fflush(stdout);

        dup2(dataPipe[1], 1);
        close(dataPipe[1]);

        if (execvp(newArgs[0], newArgs) < 0) {

            printf("Command Failed to exucute!");
            exit(3);
        }
    }

    else {

        char buf[BUFFER];
        close(dataPipe[1]);

        wait(0);
        printf("Command exexuted correctly!\n");

        while(read(dataPipe[0], buf, BUFFER) != 0) {
            printf("Here is the command's output:\n%s\n", buf);
        }

        exit(0);
    }

    return 0;
}

你一切都对了。代码中只需要几处更改就可以使一切正常工作

更改行:

    while(read(dataPipe[0], buf, BUFFER) != 0) {
        printf("Here is the command's output:\n%s\n", buf);
    }

第一个更改是移动
的打印,这是命令的输出:\n“
应该很明显。您不希望每次成功读取某些数据时都打印该行

第二个变化稍微微妙一点

该行:

printf("%s\n", buf);
与该行有很大不同:

fwrite(buf, count, 1, stdout);
printf
方法存在两个问题:

  • printf
    调用中,每次成功完成
    read
    ,都会在输出中引入换行符,这在分叉过程的输出中是不存在的

  • printf
    命令仅在
    buf
    是以null结尾的字符串时有效<代码>读取不会创建以null结尾的字符串。使用
    read
    ,您将获得一个原始字符数组。通过在需要以null结尾的字符串的位置使用
    buf
    ,可以调用未定义的行为


  • 使用
    fwrite
    而不是
    printf
    可以解决这两个问题。它不打印任何其他换行符。它只打印从管道读取的确切字节数。

    请先告诉我们您观察到了什么。只是事实而已。“程序打印‘对不起,朋友’并退出”。这是事实。“输出不会进入管道”。那将是一个理论。我确实说过纽瓦格斯会出现,但我会详细说明。输出在上面。您可能应该使用
    {”/bin/sh“,“-c”,“ls-a”,NULL}
    。但是,这种差异意味着您将看不到以点开头的名称。请检查您定义为
    缓冲区的内容。在检查了您的输出后,我认为它非常小(可能是1?),而且程序也没有列出您的文件“doit”和“doit.c”(可能是您的工作控制器中的两个文件)。将缓冲区增加到几百字节。2. 
    read
    不允许空终止缓冲区,您需要自己完成。非常感谢!我应该意识到这是实际输出,而不是我输入的命令,lol。
    printf("%s\n", buf);
    
    fwrite(buf, count, 1, stdout);