在C输入重定向问题中实现Shell

问题描述

管道工作正常。重定向也可以,我可以将两者结合起来。 但是在没有管道的情况下,重定向只能起作用。

它起作用:command1 | command2 > file 它不起作用:command1 < file | command2

对于第二个示例,我不知道错误出在哪里,在我看来这是过程:有2个命令调用,首先需要command1 < file ,并设置了 first 变量设为1,从而执行dup2( tuberia[1],STDOUT_FILENO );并替换stdout的写管道,我们将 rin 变量设置为1,以便将stdin替换为打开的文件。 exec的输出应该在写管道中。

第二,我们将 rin 设置为0,将 last 设置为1,然后执行dup2( input,STDIN_FILENO );,然后从读取管道中读取(输入,tuberia [0 ]),由于某种原因,这种方式无法正常工作。我可能不了解有关文件描述符的重要信息,感谢您的阅读和pleaaaaaaaase的帮助:我

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/wait.h>

static char* args[512];
int input,first,last,rout,rin;
char* file;
pid_t pid;
static char line[1024];
static int n = 0;


static char* skipwhite(char* s)
{
    while (isspace(*s)) ++s;
    return s;
}

static void split(char* cmd)
{
    cmd = skipwhite(cmd);
    char* next = strchr(cmd,' ');
    int i = 0;
 
    while(next != NULL) {
        next[0] = '\0';
        args[i] = cmd;
        ++i;
        cmd = skipwhite(next + 1);
        next = strchr(cmd,' ');
    }
 
    if (cmd[0] != '\0') {
        args[i] = cmd;
        next = strchr(cmd,'\n');
        next[0] = '\0';
        ++i; 
    }
 
    args[i] = NULL;
}

void command(char* cmd)                                                 
{
    split(cmd);

    //BUILT INS
    if (args[0] != NULL) {
            if (strcmp(args[0],"exit") == 0) {
                exit(0);
            }
        n += 1;
    }

    int tuberia[2];

    pipe(tuberia);  
    pid = fork();

    if (pid == 0) {

        if (first == 1 && last == 0 && input == 0) {
            dup2( tuberia[1],STDOUT_FILENO );
        } else if (first == 0 && last == 0 && input != 0) {
            dup2(input,STDIN_FILENO);
            dup2(tuberia[1],STDOUT_FILENO);
        } else{
            dup2( input,STDIN_FILENO );
            if(rout == 1)   
            {   
                int out = open(file,O_WRONLY | O_Trunc | O_CREAT,0666);
                dup2(out,STDOUT_FILENO);
                close(out);
            }
        }
        if(rin == 1)
        {   
            int in = open(file,O_RDONLY);
            dup2(in,STDIN_FILENO);
            close(in);
        }
        if (execvp(args[0],args) == -1) 
            fprintf (stderr,"ERROR: EXEC Failed!!\n");
            exit(1);
    }

    if (input != 0) 
        close(input);
 
    close(tuberia[1]);
 
    if (last == 1)
    {
        close(tuberia[0]);
    }
 
    input = tuberia[0];
    
}

void inhandler(char* cmd)
{
    char* in = strchr(cmd,'<');
    if(in != NULL)
    {
        rin = 1;
        file = in + 1;
        file = skipwhite(file);
        in[0] = '\0';
        strtok(file,"\n");
    }
    else rin = 0;
}

void outhandler(char* cmd)
{
    char* out = strchr(cmd,'>');
    if(out != NULL)
    {
        rout = 1;
        file = out + 1;
        file = skipwhite(file);
        out[0] = '\0';
        strtok(file,"\n");
    }
    else rout = 0;
}

void filter()
{
    input = 0;
    first = 1;
 
    char* cmd = line;
    char* next = strchr(cmd,'|'); 

    while (next != NULL) 
    {
        *next = '\0';
        last=0; 

        inhandler(cmd);
        command(cmd);
 
        cmd = next + 1;
        cmd=skipwhite(cmd);
        next = strchr(cmd,'|'); 
        first = 0;
    }
    last=1; 

    outhandler(cmd);
    inhandler(cmd);
    command(cmd);

    for (int i = 0; i < n; ++i)
        wait(NULL);
    n = 0;
}

void  main(void)
{                                                            
    char buf[PATH_MAX];
    while (1) {                                                                     
        printf( "%s : ",getcwd(buf,PATH_MAX)); 
        if (!fgets(line,1024,stdin)) 
            exit(0);            
        filter();                                               
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)