带管结合两个命令 [英] Combining two commands with a pipe
问题描述
我想合并在一个(不存在的)命令和管道it.By这两个命令我的意思..假设您有以下两条命令: grep的文字< file.txt的| WC -l> out.txt
的(不存在)的命令,可以重新present这两个命令可能是这样的(grepwc -l< file.txt的)
然后输出线进out.txt的数目。基本上这些(grepwc)命令应该有相同的行为 grep的文字< file.txt的| WC -l> out.txt
但较短。
I'm trying to "merge" two commands in one (nonexistent) command and pipe it.By this I mean.. Suppose that you have these two commands: grep text < file.txt | wc -l > out.txt
, the (nonexistent) command that could represent this two commands could be something like (grepwc -l < file.txt)
which then outputs the number of lines into the out.txt. Basically these (grepwc) command should have the same behavior as the grep text < file.txt | wc -l > out.txt
but shorter.
我想这样的事情,但我觉得我的做法是远远地实现目标。我使用了一个名为commlist结构,其中包含已被CMD,argc和argv解析的命令。 inputfile中和OUTPUTFILE是这些文件上使用的路径名的open()
I tried something like this, but I think my approach is far to accomplish the goal. I use a structure named commlist which contains the commands already parsed by cmd, argc and argv. inputfile and outputfile are the pathnames of the files used on open().
我使用的结构。
typedef struct command {
char *cmd;
int argc;
char *argv[MAXARGS+1];
struct command *next;
} COMMAND;
和code:
void execute(COMMAND *commlist) {
int fd[2];
pid_t pid;
int n_pipes=2; //pipes needed
COMMAND *aux = commlist;
int i;
for(i=0;i<n_pipes; i++){
int oldfd = 0;
if(fd[0]!=0){
close(fd[1]);
oldfd = fd[0];
}
pipe(fd);
if((pid=fork())<0){perror("Fork Failed");}
else
if(pid == 0){
if(inputfile!=NULL){
int in = open(inputfile,O_RDONLY);
dup2(in,STDIN_FILENO);
inputfile = NULL;
}
if(outputfile != NULL){
int out = open(outputfile, O_RDWR |O_CREAT | O_TRUNC, S_IRWXU);
dup2(out,STDOUT_FILENO);
outputfile = NULL;
}
if(oldfd)
dup2(oldfd,STDIN_FILENO);
if(commlist->cmd == "grepwc"){
if(i==0){
if(execlp("grep","grep","celio",NULL)<0){
perror("Bad command");
exit(1);
}
}
if(i==1){
if(execlp("wc","wc","-l",NULL) < 0){
perror("Bad command");
exit(1);
}
}
}
}//child
}
}
满code是在这里:
The full code is here:
推荐答案
您的做法确实有点过于复杂。这可以只用一个子进程和单个管(正如在原壳命令)来实现。让我们来看看它:
Your approach is indeed a bit overcomplicated. This can be achieved with just one childprocess and a single pipe (just as in the original shell command). Let's have a look at it:
grep text < file.txt | wc -l > out.txt
这
- 创建一个管道
- 叉两种工艺
- 的grep使得写到管道
- 使WC从管道中读
但它足以叉只有一个进程,因为我们不需要返回到父进程。这将导致以下code:
But it is enough to fork only one process, since we do not need to return to the parent process. This results in the following code:
#include <stdlib.h>
#include <unistd.h>
int main (void) {
int fd[2];
pipe(fd);
if (fork()) {
// Child process
dup2(fd[0], 0); // wc reads from the pipe
close(fd[0]);
close(fd[1]);
execlp("wc", "wc", "-l", NULL);
} else {
// Parent process
dup2(fd[1], 1); // grep writes to the pipe
close(fd[0]);
close(fd[1]);
execlp("grep", "grep", "celio", NULL);
}
exit(EXIT_FAILURE);
}
的退出()
如果 execlp之一()
的失败也只能达到。
The exit()
is only reached if one of the execlp()
's fails.
这篇关于带管结合两个命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!