问题在C管道命令 [英] Problem with piping commands in C

查看:130
本文介绍了问题在C管道命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创造℃,Unix的一个简单的shell。我已经能够做的命令和执行的所有解析,但我在使用的管道有问题。我认为问题是,我不挂钩到了第二个命令的输入正确的管道。

例如,如果我键入ls |厕所,它会在WC的命令,我认为这是因为它在等待输入之后暂停。我认为这个问题是,当我使用dup2(阅读[I],0),其不挂钩到正确的管道。

我知道这是一个有点宽泛的问题,但如果有任何指针,我可以搞定,我会AP preciate它。以下是创建新的进程,并试图管code它们。

  INT个行业[2];
诠释阅读[num_cmds]
诠释写[num_cmds]INT磷;
为(p值= 0; P&下; num_cmds,P ++)
{
读取[P] = -1;
写[P] = -1;
}诠释J;
为(J = 0; J< num_cmds-1; J ++)//创建命令管道
{
INT个行业[2];
管(个行业);
阅读[J + 1] =个行业[0];
写[J] =个行业[1];
}INT I = 0;
对于(i = 0; I< num_cmds;我++)
{
cmd_args = parse_cmd(CMDS [I],OUTPUT_FILE,INPUT_FILE,&安培; run_bg); // Get命令和args将为pid_t childpid;
INT状态;
childpid =叉();如果(childpid> = 0)
{
如果(childpid == 0)
{
如果(写入由[i]!= -1)
{
dup2(写入由[i],1);
关闭(写入[I]);
}如果(读取由[i]!= -1)
{
dup2(读数[I],0);
关闭(阅读[I]);
}INT H;
对于(H = 0; H< num_cmds; H ++)
{
关闭(写入[H]);
关闭(阅读[H]);
}如果(execvp(cmd_args [0],cmd_args)== - 1)
{
PERROR(问题的命令);
出口(0);
}
}
其他
{
等待(安培;状态);
INT米;
为(M = 0; M&下; num_cmds; M +)
{
如果关闭(写入[M]。)(写入[M]!= -1);
如果(读[M]!= -1)关闭(读[M]);
}
}
}
其他
{
PERROR(叉);
继续;
}
INPUT_FILE [0] = 0;
OUTPUT_FILE [0] = 0;
run_bg = 0;
}}

搜索结果

更新:我能弄清楚,这要感谢理查德。这是在错误的顺序关闭文件描述符,而不是关闭部分在所有的组合。这里的工作code。

  INT个行业[2];
诠释阅读[num_cmds]
诠释写[num_cmds]INT磷;
为(p值= 0; P&下; num_cmds,P ++)
{
读取[P] = -1;
写[P] = -1;
}诠释J;
为(J = 0; J< num_cmds-1; J ++)
{
INT个行业[2];
管(个行业);
阅读[J + 1] =个行业[0];
写[J] =个行业[1];
}INT I = 0;
对于(i = 0; I< num_cmds;我++)
{
cmd_args = parse_cmd(CMDS [I],OUTPUT_FILE,INPUT_FILE,&安培; run_bg);将为pid_t childpid;
INT状态;
childpid =叉();如果(childpid> = 0)
{
如果(childpid == 0)
{
如果(写入由[i]!= -1)
{
关闭(1);
dup2(写入由[i],1);
}如果(读取由[i]!= -1)
{
关闭(0);
dup2(读数[I],0);
}如果(execvp(cmd_args [0],cmd_args)== - 1)
{
PERROR(问题的命令);
出口(0);
}
}
其他
{等待(安培;状态);
关闭(写入[I]);如果(I 0)
{
关闭(阅读[I]);
}
}
}
其他
{
PERROR(叉);
}
INPUT_FILE [0] = 0;
OUTPUT_FILE [0] = 0;
run_bg = 0;
}


解决方案

我认为你的问题可能是你等待循环内的每个进程,然后关闭所有的文件描述符。这使得标准输入的文件描述符到dup2下一次调用无效()和成果为下道工序留不变。

只是一个猜测,我还没有运行code。

I'm trying to create a simple shell in C for Unix. I've been able to do all the parsing of commands and execution, but I'm having a problem with piping. I think the problem is that I'm not hooking into the correct pipe for the input of the second command.

For example, if I type "ls | wc", it will pause after the "wc" command, which I think is because its waiting for input. I think the problem is when I use dup2(reading[i],0), and its not hooking into the correct pipe.

I know this is a bit of a broad question, but if there are any pointers I could get, I would appreciate it. Here is the code that creates new processes and tries to pipe them.

    int fileds[2];
	int reading[num_cmds];
	int writing[num_cmds];

	int p;
	for(p=0; p < num_cmds; p++)
	{
		reading[p] = -1;
		writing[p] = -1;
	}

	int j;
	for(j=0; j < num_cmds-1; j++)    //Create pipes for commands
	{
		int fileds[2];
		pipe(fileds);
		reading[j+1] = fileds[0];
		writing[j] = fileds[1];
	}

	int i = 0;
	for(i = 0; i < num_cmds;i++)
	{			
		cmd_args = parse_cmd(cmds[i],output_file,input_file,&run_bg); //Get command and args

		pid_t childpid;
		int status;
		childpid=fork();

		if (childpid >= 0) 
		{
			if (childpid == 0) 
			{				
				if(writing[i] != -1)
				{
					dup2(writing[i],1);
					close(writing[i]);
				}

				if(reading[i] != -1)
				{
					dup2(reading[i],0);
					close(reading[i]);
				}

				int h;
				for(h = 0; h < num_cmds; h++)
				{
					close(writing[h]);
					close(reading[h]);
				}

				if(execvp(cmd_args[0],cmd_args) == -1) 
				{
					perror("Problem with command");
					exit(0);
				}
			}
			else 
			{
				wait(&status);
				int m;
				for(m = 0; m < num_cmds; m++)
				{
					if( writing[m] != -1) close(writing[m]);
					if( reading[m] != -1) close(reading[m]);
				}
			}
		}
		else 
		{
			 perror("fork"); 
			 continue;
		}


		input_file[0] = 0;
		output_file[0] = 0;
		run_bg = 0;
	}

}



UPDATE: I was able to figure it out, thanks to Richard. It was a combination of closing the file descriptors in the wrong order and not closing some at all. Here's the working code.

int fileds[2];
	int reading[num_cmds];
	int writing[num_cmds];

	int p;
	for(p=0; p < num_cmds; p++)
	{
		reading[p] = -1;
		writing[p] = -1;
	}

	int j;
	for(j=0; j < num_cmds-1; j++)
	{
		int fileds[2];
		pipe(fileds);
		reading[j+1] = fileds[0];
		writing[j] = fileds[1];
	}

	int i = 0;
	for(i = 0; i < num_cmds;i++)
	{			
		cmd_args = parse_cmd(cmds[i],output_file,input_file,&run_bg);

		pid_t childpid;
		int status;
		childpid=fork();

		if (childpid >= 0) 
		{
			if (childpid == 0) 
			{				
				if(writing[i] != -1)
				{
					close(1);
					dup2(writing[i],1);
				}

				if(reading[i] != -1)
				{
					close(0);
					dup2(reading[i],0);
				}

				if(execvp(cmd_args[0],cmd_args) == -1) 
				{
					perror("Problem with command");
					exit(0);
				}
			}
			else 
			{

				wait(&status);
				close(writing[i]);

				if(i > 0) 
				{
					close(reading[i]);
				}
			}
		}
		else 
		{
			 perror("fork");
		}


		input_file[0] = 0;
		output_file[0] = 0;
		run_bg = 0;
	}

解决方案

I think your problem may be that you wait for each process inside the loop and then close all the file descriptors. This makes the file descriptors invalid for the next call to dup2() and results in stdin for the next process staying unchanged.

Just a guess, I haven't run the code.

这篇关于问题在C管道命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆