【发布时间】:2018-03-12 21:48:36
【问题描述】:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <sys/utsname.h>
#include <unistd.h>
using namespace std;
//first comannd to execute
void first(int pipeA[], char * command[]){
//redirect STDOUT to pipe[1] and close the pipe[0] we are not using
dup2(pipeA[1], 1);
close(pipeA[0]);
execvp(command[0], command);
printf(" first error ");
exit(127);
}
void second(int pipeA[], char * command2[]){
//redirect STDIN to pipe[0] and close the pipe[1] that we are not using
dup2(pipeA[0], 0);
close(pipeA[1]);
//This doesnt seem to be doing anything at times
execvp(command2[0], command2);
perror(" second error ");
exit(127);
}
int main(void)
{
char buf[1024];
char * command[1024];// this one is the first input usually 'cat file.txt'
//Use only one or the other, sort never works and 'grep U' works sometimes
char * command2[] = {(char *)"sort", (char *) NULL};// this is wants to sort the above 'command[1024]' and its use in the second function
//char * command2[] = {(char *)"grep",(char *)"U",(char *) NULL};// this is wants to grep the above 'command[1024]' and its use in the second function
//variables for forks and waits
pid_t pid;
pid_t pid2;
int status;
int status2;
//see if || exists not in use currently
bool pipeExists = false;
//create pipe
int pipeA[2];
pipe(pipeA);
//first line and ask for input,
cout<< "command: ";
while (fgets(buf,1024,stdin) != NULL)
{
buf[strlen(buf) -1] = 0;
//Save input into buf and tokenized? it
//NOT YET CATCHING ||, im only debugging and usually use use 'cat file.txt'
int number =0;
char * ptr;
ptr = strtok(buf, " ");
while(ptr != NULL){
command[number] = ptr;
ptr = strtok(NULL, " ");
number++;
}
//***************************************************************
//1. do the pipes go here or after the children?
//They seem to be working here but im not really sure where they should be
close(pipeA[0]);
close(pipeA[1]);
//create first child
if ((pid = fork()) <0)
printf("fork error");
else if (pid == 0)
{ /* child */
//create second child INSIDE ORIGINAL CHILD
//2. Is this correct? or is there not supposed to be grandchildren?
if ((pid2 = fork()) <0)
printf("fork 2 error");
else if (pid == 0)
{ /* child */
second(pipeA, command2);
printf("couldn't execute: %s");
exit(127);
}
//first command from buf
first(pipeA, command);
printf("couldn't execute: %s");
exit(127);
//3. Do I wait for this child aswell?
if ( (pid2 = waitpid(pid2, &status2, 0)) < 0)
printf("waitpid error");
}
/* parent */
if ( (pid = waitpid(pid, &status, 0)) < 0)
printf("waitpid error");
printf("Command :");
//***************************************************************
//***************************************************************
//SECOND WAY OF DOING IT
// THIS WAY IT TRIGGERS WAITPID ERRORS.
/*
close(pipeA[0]);
close(pipeA[1]);
//create first child
if ((pid = fork()) <0)
printf("fork error");
else if (pid == 0)
{
first(pipeA, command);
printf("couldn't execute: %s");
exit(127);
}
//create second child INSIDE ORIGINAL CHILD
if ((pid2 = fork()) <0)
printf("fork 2 error");
else if (pid == 0)
{
second(pipeA, command2);
printf("couldn't execute: %s");
exit(127);
}
//3. Do I wait for this child aswell?
if ( (pid2 = waitpid(pid2, &status2, 0)) < 0)
printf("waitpid error");
if ( (pid = waitpid(pid, &status, 0)) < 0)
printf("waitpid error");
printf("Command :");
*/
//***************************************************************
}
exit(0);
}
代码显示的内容与它的问题差不多。
我需要创建一个接收命令(“cat file.txt”)的 microshell,并使用 execvp() 执行它,并将其通过管道传送到另一个进程,并通过“sort”或“grep U”或其他任何方式执行。
只是我的进程有时无法正确运行或不会显示任何内容。我已经关闭了所有地方的管道,但什么也没发生。
【问题讨论】:
-
你试过什么?发生什么了?尝试在 strace 下运行。尝试创建一个更简单的问题示例,并将问题限制在无法正常工作的一件事上。
-
欢迎来到 Stack Overflow!请edit你的问题告诉我们你做了什么样的调试。我希望您已经在 Valgrind 或类似的检查器中运行了您的minimal reproducible example,并使用诸如 GDB 之类的调试器进行了调查。确保您也启用了全套编译器警告。这些工具告诉了你什么,它们缺少什么信息?并阅读 Eric Lippert 的 How to debug small programs。
-
请不要将问题更改为非问题。我已将您的修订移至社区 wiki 答案。
标签: c++ linux shell process piping