【发布时间】:2020-05-12 07:44:58
【问题描述】:
我在创建从命令行获取参数的简单 C 程序时遇到问题,最后一个参数是文件的路径。程序在给定文件上运行cat 命令,然后在 cat 的结果上运行 tr。 Tr 从命令行获取参数(最后一个参数除外)。我收到错误:
缺少操作数。
写入错误:断管。
我不确定错误在哪里......
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WRITE_END 1
#define READ_END 0
int main(int argc, char* argv[]){
if(argc < 2){
printf("\nPROVIDE AN ARGUMENT\n");
return 1;
}
const char * file = argv[argc - 1];
char ** args = calloc(argc - 2, sizeof(char*));
for( int i = 1; i<argc-2; i++){
args[i - 1 ] = argv[i];
}
int fd[2];
pipe(fd);
pid_t child;
if((child = fork()) == -1)return 2;
if(child == 0){
dup2(fd[WRITE_END], STDOUT_FILENO);
close(fd[READ_END]);
close(fd[WRITE_END]);
execlp("cat", "cat", file, (char*)NULL);
exit(1);
}
else{
dup2(fd[READ_END], STDIN_FILENO);
close(fd[WRITE_END]);
close(fd[READ_END]);
execlp("tr", "tr", *args, (char*)NULL);
exit(1);
}
close(fd[0]);
close(fd[1]);
wait(0);
wait(0);
return 0;
}
【问题讨论】:
-
dup(fd[0]);这并不像您认为的那样。您可能想研究man dup2, -
你的
args变量搞砸了;您实际上是将char *的数组复制到char的数组中。当您真正想要的是execvp时,这似乎是使execlp工作的错误尝试。 -
现在看来是这个
if(child == 0){ dup2(fd[WRITE_END], STDOUT_FILENO); close(fd[READ_END]); close(fd[WRITE_END]); execlp("cat", "cat", file, (char*)NULL); exit(1); } else{ dup2(STDIN_FILENO, fd[READ_END]); close(fd[WRITE_END]); close(fd[READ_END]); execlp("tr", "tr", *args, (char*)NULL); exit(1); }我认为管道仍然存在一些问题。这对我来说真的是一个模糊的话题:(( -
在 cmets 中阅读代码真的很难。请编辑您的问题以包含新版本。
-
你处理管道的方式没有问题。问题在于 args 的分配和复制以及 exec 函数的使用。请参阅下面的答案。