C - exec没有输出到管道中

xjs*_*16x 3 c stdin stdout pipe exec

我正在制作一个程序,最终能够(理论上)为传递给它的任何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;
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

$ ./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:


@
Run Code Online (Sandbox Code Playgroud)

R S*_*ahu 5

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

改变线条:

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

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

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

第二个变化有点微妙.

这条线:

printf("%s\n", buf);
Run Code Online (Sandbox Code Playgroud)

与行完全不同:

fwrite(buf, count, 1, stdout);
Run Code Online (Sandbox Code Playgroud)

该方法存在几个问题printf:

  1. printf调用中,您将在每次成功完成时为输出引入换行符,这些换行符read不在forked进程的输出中.

  2. printf命令仅在buf以null结尾的字符串时有效.read不会创建以null结尾的字符串.有了read,您将获得一系列原始字符.通过buf在需要以null结尾的字符串的位置使用,您将调用未定义的行为.

使用fwrite而不是printf处理这两个问题.它不会打印任何其他换行符.它只打印从管道读取的确切字节数.