我正在尝试实现以下简单的UNIX命令:
cat -n < file.txt
其中file.txt只包含一个整数“5”。
我很好的输出重定向,但这个输入重定向让我难过。这是我试图模仿上述命令:
int f_des[2];
char *three[]={"cat", "-n", NULL};
// Open a pipe and report error if it fails
if (pipe(f_des)==-1){
perror("Pipe");
exit(1);
}
int filed=open("file.txt", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
//fork child
if(fork()==0){
dup2(f_des[1], filed);
close(f_des[0]);
}
//fork child
if(fork()==0){
dup2(f_des[0], fileno(stdin));
close(f_des[1]);
execvp(three[0], three);
}
我收到以下错误:
cat: -: Input/output error
我的想法是我通过管道发送文件(文件的fd),管道的另一端将从管道收集文件的内容作为标准输入,然后我将执行“cat -n”文件的内容位于标准输入中。
答案 0 :(得分:2)
您没有说明背景信息。如果你想要做的只是实施cat -n < file
,你可以完全免除pipe
和fork
。
这应该足够了:
filed = open("file.txt", O_RDONLY);
dup2(filed, 0); // make file.txt be stdin.
close(filed);
execvp(three[0], three);
如果您要在其他计划中实施此功能并需要在cat
通话后恢复,则需要fork
,但您只需要拨打一次。您不需要pipe
。
所以你会这样做:
int ret;
if ((ret = fork()) == 0) {
// in child
// open file, dup2, execvp...
}
// in parent
wait(&ret); // wait for child to exit
// do other stuff...
fork
克隆了该过程的副本。它看起来像你之前的那个,除了PID和fork
的返回值。
检查fork()的返回值会告诉您该进程是子进程还是父进程。
如果返回值为零,那么您就在孩子身边。在if(ret == 0) {}
部分中执行您喜欢的操作。在你的情况下,你做execvp
最终会退出并带走孩子。
如果返回值不为零,则表示您在父级中。您将跳过if(ret == 0) {}
部分。在继续之前,你应该让孩子wait
退出。