我正在创建一个程序,最终能够(理论上)为传递给它的任何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:
@
答案 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
方法有几个问题:
在printf
调用中,每次成功完成read
时,都会为输出引入换行符,这些换行符不在分叉进程的输出中。
仅当printf
是以空字符结尾的字符串时,buf
命令才有效。 read
不会创建以null结尾的字符串。使用read
,您将获得一组原始字符。通过在期望以null结尾的字符串的位置使用buf
,您将调用未定义的行为。
使用fwrite
代替printf
可以解决这两个问题。它不会打印任何其他换行符。它只打印从管道读取的确切字节数。