在C shell执行管道(UNIX) [英] Implementing Pipes in a C shell (Unix)

查看:108
本文介绍了在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屋!

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