玩具外壳不正确 [英] Toy shell not piping correctly
问题描述
我不会撒谎。这是一个家庭作业问题。然而,就我而言,点已经走了宝宝走了。现在,我只是寻找一个答案,因为我 - 我可能是疯了。
I'm not going to lie. This is a homework question. However, as far as I'm concerned, the points are gone baby gone. Right now, I'm just looking for an answer, because I -think- I might be insane.
这个程序的目标是执行命令 ps -A | grep(inputstring)| wc -l </ code>的方式类似于shell如何做。所以,我产生的进程,让他们互相等待。最新的进程,大孙子
进程。在它之前 execlp(ps,ps, - A,NULL)
ps -A execlp
,我确保它的标准输出到管道输出。下一个进程是 wait()
ing,并且已经设置好了,以便输入管道进入标准输入,标准输出到输出管道,它将执行grep,等等。
The goal of this program is to execute the command ps -A | grep (inputstring) | wc -l
in a way similar to how the shell does it. So, I spawn the processes, and have them wait on each other. The newest process, the great-grandchild, execlp("ps","ps","-A",NULL)
which replaces itself with the ps -A
process. Before it execlp
, I make sure its standard output is going to the pipe output. The next process in line is wait()
ing, and already has itself set up so that the input pipe goes to standard in, and standard out goes to the output pipe, and it will execute grep, and so on.
我几乎肯定我已正确设置。然而...程序做。不。工作。
I'm almost positive I have it set up correctly. And yet... the program does. Not. Work.
#include <stdlib.h>
#include <iostream>
#include <string>
#define MAXLINE 1500
#define READ 0
#define WRITE 1
using namespace std;
int main( int argc, char** argv ) {
//* start of input block
if ( argc != 2 ) {
cout << "Usage: ./a.out arg1" << endl;
return 0;
}
string in = argv[1];
// end of input block */
int pipeA[2], pipeB[2], pid, stat;
// get our first set of pipes
if ( pipe(pipeA) < 0 ) {
cerr << "Pipe error.\n";
exit(-1);
}
if ( pipe(pipeB) < 0 ) {
cerr << "Pipe error.\n";
exit(-1);
}
// make the first fork
if ( (pid = fork() ) < 0 ) { cerr << "Fork error.\n"; exit(-1); }
if ( pid > 0 ) { // parent case
wait(&stat);
} else { // child case
if ( (pid = fork()) < 0 ) { cerr << "Fork Error\n"; exit(-1); }
if ( pid > 0 ) { // child
wait(&stat);
dup2(pipeA[READ],READ);
execlp("wc","wc","-l",NULL);
} else { // grand-child
if ( (pid = fork()) < 0 ) { cerr << "Fork Error\n"; exit(-1); }
if ( pid > 0 ) { // still grand-child
wait(&stat);
dup2(pipeB[READ],READ);
dup2(pipeA[WRITE],WRITE);
close(pipeB[READ]);
execlp("grep","grep",in.c_str(),NULL);
} else { // great grand-child
dup2(pipeB[WRITE],WRITE); // t now goes to pipeB[1]
close(READ);
close(pipeB[READ]);
execlp("ps", "ps", "-A", NULL);
}
}
}
return 0;
}
编辑:更改为我的代码的双管道变体。 >
Changed to the two-pipe variant of my code.
推荐答案
我几乎肯定这是你想要做的。事先对错误的编码道歉。它在这里有点晚,我真的应该睡觉了:
I'm virtually certain this is what you're trying to do. Apologies in advance for the sloppy coding. its somewhat late here and I really should be sleeping right now:
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#define READ 0
#define WRITE 1
// ps -A | grep argv[1] | wc -l
int main( int argc, char** argv )
{
//* start of input block
if ( argc != 2 )
{
std::cout << "Usage: ./a.out arg1" << std::endl;
return 0;
}
// make local copy of argument
std::string in = argv[1];
int fd1[2], fd2[2], pid;
// allocate two pipe sets
if (pipe(fd1) < 0 || pipe(fd2) < 0)
{
perror("Failed to create pipe.");
return EXIT_FAILURE;
}
// launch first child process.
if ((pid = fork()) < 0)
{
perror("Failed to fork child(1)");
return EXIT_FAILURE;
}
if (pid == 0)
{
// wc -l process.
// stdin = fd2(read)
close(fd1[READ]);
close(fd1[WRITE]);
close(fd2[WRITE]);
dup2(fd2[READ],STDIN_FILENO);
execlp("wc","wc","-l",NULL);
}
// fork again. this time for grep
if ((pid = fork()) < 0)
{
perror("Failed to fork child(2)");
return EXIT_FAILURE;
}
if (pid == 0)
{
// grep argv[1] process.
// stdin = fd1(read)
// stdout = fd2(write)
close(fd1[WRITE]);
close(fd2[READ]);
dup2(fd2[WRITE], STDOUT_FILENO);
dup2(fd1[READ], STDIN_FILENO);
execlp("grep", "grep", in.c_str(), NULL);
}
// fork once more. this time for ps -A
if ((pid = fork()) < 0)
{
perror("Failed to fork child(3)");
return EXIT_FAILURE;
}
if (pid == 0)
{
// ps -A process.
// stdout = fd1(write)
close(fd2[WRITE]);
close(fd2[READ]);
close(fd1[READ]);
dup2(fd1[WRITE], STDOUT_FILENO);
execlp("ps", "ps", "-A", NULL);
}
int stat=0;
wait(&stat);
return EXIT_SUCCESS;
}
在我的系统上, ps -A
报告141行,其中41行中有 System
字样,通过运行 ps -A | grep系统| wc -l </ code>。上述代码生成的输出完全相同。
On my system, ps -A
reports 141 lines, of those 41 have the word System
somewhere within, verified by simply running ps -A | grep System | wc -l
. The above code generates precisely the same output.
希望它帮助你。
这篇关于玩具外壳不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!