在C shell执行管道(UNIX) [英] Implementing Pipes in a C shell (Unix)
问题描述
基本上我已经使用标准的POSIX命令创建一个空壳,我希望能够实现管道为好。现在它正确处理命令,并且可以用&放后台处理;.不过,我需要能够使用管道|和>>为好。
例如这样的事情:
猫文件1文件2 >>文件3
猫文件1文件2 |更多
更多文件1 | grep的东西
下面是code我目前。我也想避免SYSTEM呼叫。我知道ü需要使用dup2,但方式我做我的code是一个有点古怪,所以即时通讯希望如果有人能告诉我,如果它是可行的实施本code管?谢谢!我知道dup2被使用,但也即时高清。如何实现>>和困惑|
的#include< SYS / wait.h>
#包括LT&; SYS / types.h中>
#包括LT&;&unistd.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;串GT;
#包括LT&;&iostream的GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&stdio.h中GT;使用命名空间std;
无效执行(字符*命令[],布尔BG)
{
//智力状态是针对waitpid函数纯粹是,fork()的设置像正常。
INT状态;
将为pid_t PID =叉();
开关(PID)
{
情况下0:
execvp(命令[0],命令); 如果(execvp(命令[0],命令)== -1)
{
COUT<< 找不到命令<< ENDL;
出口(0);
} 默认:
如果(BG == 0)
{
waitpid函数(PID,和放大器;状态,0);
//调试COUT<< DEBUG:儿童完成<< ENDL;
}
}}
布尔ParseArg(字符*提示,字符*命令[],CHAR看书[],布尔BG)
{ fprintf中(标准错误,myshell>);
cin.getline(看书,50);
提示= strtok的(看书,);
INT I = 0; 而(提示!= NULL)
{
命令[I] =提示;
如果(的strcmp(命令[I]中,与&)== 0){
//调试COUT<< &放大器;找到了;
命令[我] = NULL;
返回true;
}
//调试COUT<<命令[1] - ;< ;
我++;
提示=的strtok(NULL,); }
返回false;
}清理无效(字符*命令[])
{
//清洁阵
对于(int类型的= 0; A< 50;一++)
{
命令[A] = NULL;
}
}诠释的main()
{
字符*提示;
字符*命令[50];
看书的char [50];
布尔BG = FALSE; 而(命令[0]!= NULL)
{ 清理(命令);
BG = ParseArg(提示,命令,看书,BG);
如果(STRCMP(命令[0],退出)== 0 || STRCMP(指令[0],跳槽)== 0)
{
打破;
} 其他
{
执行(命令,BG);
} } 返回1;}
您应该能够实现管道输出重定向你的shell,但也有几件事情,我注意到:
您code读取输入,解析和输出混合在一起,可能要分开这个功能。
strtok的不作为shell命令的语法分析器工作得很好。这将非常简单的命令工作,但你可能要考虑创建或找到更好的解析器。像A命令回声世界你好
将与你当前的分析方法有问题。
您可能需要为牵着你解析命令创建一个简单的结构。
下面是一些伪code,让你开始:
的#define MAX_LINE 10000
#定义MAX_COMMANDS 100
#定义MAX_ARGS 100//结构来遏制解析的输入
结构命令
{
//使用IO重定向这些更改
FILE *输入; //应该默认为STDIN
FILE *输出; //应该默认为STDOUT INT num_commands;
INT num_args [MAX_COMMANDS] // args作为每个命令的数
字符* command_list [MAX_COMMANDS] //包含要运行的程序
字符* args_list [MAX_COMMANDS] [MAX_ARGS]; //每个命令的ARGS
布尔background_task;
布尔追加;
}诠释的main()
{
字符输入[MAX_LINE] 而(1)
{
结构CMD命令; print_prompt();
的read_input(输入);
parse_input(输入,功放及; CMD);
执行(安培; CMD);
}
}
祝你好运与这个项目!
Basically I have created a shell using standard POSIX commands, I want to be able to Implement Piping as well. Right now it handles commands correctly, and can do background processing with &. But I need to be able to pipe using | and >> as well. For example something like this: cat file1 file2 >> file3 cat file1 file2 | more more file1 | grep stuff
Here is the code I have currently. I also want to AVOID "SYSTEM" calls. I know U need to use dup2, but the way I did my code is a bit odd, so im hoping if someone can tell me if it is feasible to implement pipes in this code? thanks! I know dup2 is used, but also im def. confused at how to implement >> as WELL as |
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <string>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
void Execute(char* command[],bool BG)
{
//Int Status is Used Purely for the waitpid, fork() is set up like normal.
int status;
pid_t pid = fork();
switch(pid)
{
case 0:
execvp(command[0], command);
if(execvp(command[0], command) == -1)
{
cout << "Command Not Found" << endl;
exit(0);
}
default:
if(BG == 0)
{
waitpid(pid, &status, 0);
//Debug cout << "DEBUG:Child Finished" << endl;
}
}
}
bool ParseArg(char* prompt, char* command[], char Readin[],bool BG)
{
fprintf(stderr, "myshell>");
cin.getline(Readin,50);
prompt = strtok(Readin, " ");
int i = 0;
while(prompt != NULL)
{
command[i] = prompt;
if(strcmp(command[i], "&") == 0){
//Debug cout << "& found";
command[i] = NULL;
return true;
}
//Debug cout << command[i] << " ";
i++;
prompt = strtok(NULL, " ");
}
return false;
}
void Clean(char* command[])
{
//Clean Array
for(int a=0; a < 50; a++)
{
command[a] = NULL;
}
}
int main()
{
char* prompt;
char* command[50];
char Readin[50];
bool BG = false;
while(command[0] != NULL)
{
Clean(command);
BG = ParseArg(prompt, command, Readin, BG);
if(strcmp(command[0], "exit") == 0 || strcmp(command[0], "quit") == 0 )
{
break;
}
else
{
Execute(command,BG);
}
}
return 1;
}
You should be able to implement pipes and output redirection with your shell, but there are a few things I noticed:
- Your code for reading input, parsing, and output are mixed together, you may want to separate this functionality.
-
strtok won't work very well as a parser for shell commands. It will work for very simple commands, but you may want to look into creating or finding a better parser. A command like
echo "hello world"
will be problematic with your current parsing method. - You may want to create a simple structure for holding your parsed commands.
Here is some pseudocode to get you started:
#define MAX_LINE 10000
#define MAX_COMMANDS 100
#define MAX_ARGS 100
// Struct to contain parsed input
struct command
{
// Change these with IO redirection
FILE *input; // Should default to STDIN
FILE *output; // Should default to STDOUT
int num_commands;
int num_args[MAX_COMMANDS]; // Number of args for each command
char* command_list[MAX_COMMANDS]; // Contains the programs to be run
char* args_list[MAX_COMMANDS][MAX_ARGS]; // The args for each command
boolean background_task;
boolean append;
}
int main()
{
char input[MAX_LINE];
while (1)
{
struct command cmd;
print_prompt();
read_input(input);
parse_input(input, &cmd);
execute(&cmd);
}
}
Good luck with this project!
这篇关于在C shell执行管道(UNIX)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!