C - exec没有输出到管道中

时间:2014-09-09 04:49:49

标签: c exec pipe stdout stdin

我正在创建一个程序,最终能够(理论上)为传递给它的任何shell命令工作。我的问题是运行的exec不会将其输出放入管道,而是在运行时看起来好像初始调用是进入管道的?我试过先冲洗stdout但它不起作用。任何帮助表示赞赏!

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;
}

这是输出:

$ ./doit ls -a                                       
Command exexuted correctly!
Here is the command's output:
d
@
Here is the command's output:
o
@
Here is the command's output:
i
@
Here is the command's output:
t
@
Here is the command's output:
@
Here is the command's output:
d
@
Here is the command's output:
o
@
Here is the command's output:
i
@
Here is the command's output:
t
@
Here is the command's output:
.
@
Here is the command's output:
c
@
Here is the command's output:


@

1 个答案:

答案 0 :(得分:5)

你的一切都是正确的。您的代码中只需要进行几项更改即可使一切正常运行。

更改行:

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

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

第一次改变,移动"Here is the command's output:\n"的印刷应该是显而易见的。每次成功读取某些数据时,您都不希望打印该行。

第二个变化有点微妙。

该行:

printf("%s\n", buf);

与该行完全不同:

fwrite(buf, count, 1, stdout);

printf方法有几个问题:

  1. printf调用中,每次成功完成read时,都会为输出引入换行符,这些换行符不在分叉进程的输出中。

    < / LI>
  2. 仅当printf是以空字符结尾的字符串时,buf命令才有效。 read不会创建以null结尾的字符串。使用read,您将获得一组原始字符。通过在期望以null结尾的字符串的位置使用buf,您将调用未定义的行为。

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