UNIX C编程输入重定向命令

时间:2014-11-03 04:45:43

标签: c unix pipe file-descriptor

我正在尝试实现以下简单的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”文件的内容位于标准输入中。

1 个答案:

答案 0 :(得分:2)

您没有说明背景信息。如果你想要做的只是实施cat -n < file,你可以完全免除pipefork

这应该足够了:

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退出。