【问题标题】:UNIX C programming input re-direction commandUNIX C 编程输入重定向命令
【发布时间】:2014-11-03 04:45:42
【问题描述】:

我正在尝试实现以下简单的 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

我的想法是我通过管道发送filed(文件的fd),管道的另一端将从管道收集文件的内容作为标准输入,然后我将执行“cat -n”文件的内容位于标准输入中。

【问题讨论】:

  • 为什么要以输出模式打开文件?为什么要调用 fork() 三次(第二次将在第一次的父子级中运行)。
  • 我认为您应该以读取模式打开文件。你在哪里使用变量“三”?
  • 所以代码是正确的,只是我需要以不同的方式打开文件?如果是这样,我应该在 open() 中使用什么标志。啊,对不起,我是想在close(f_des[0]);之后退出进程;
  • 我将 WRONLY 更改为 RDONLY,并在 close(f_des[0]) 后退出(),但现在它在更正后完全没有输出:S

标签: c unix pipe file-descriptor


【解决方案1】:

您没有指明上下文。如果您只想实现cat -n &lt; 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 让孩子退出。

【讨论】:

  • 非常感谢!我现在明白了。我想我是在想这个问题。
  • 很高兴为您服务。
猜你喜欢
  • 2011-12-15
  • 2014-04-30
  • 1970-01-01
  • 2018-10-06
  • 2015-06-26
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多