Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C型壳体中的多管道_C_Linux_Shell_Ipc - Fatal编程技术网

C型壳体中的多管道

C型壳体中的多管道,c,linux,shell,ipc,C,Linux,Shell,Ipc,谁能告诉我这个代码有什么问题吗。我能够成功地写入管道,但当我使用管道输出端作为另一个命令的输入时,无法获得输出。下面是代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> //for pid_t fork() and other system calls #include <signal.h> //for sig

谁能告诉我这个代码有什么问题吗。我能够成功地写入管道,但当我使用管道输出端作为另一个命令的输入时,无法获得输出。下面是代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>     //for pid_t fork() and other system calls
#include <signal.h>     //for signal()
#include <sys/types.h>


void command_EXECUTER(char *args[]);
void command_HANDLER(char *args[]);
int pipe_EXECUTER(char *args[], int in, int pos);

void shell_INIT(){

    int is_interactive = isatty(STDOUT_FILENO);

    if(is_interactive){



    }

}

int main(int argc, char *argv[], char **envp){

    char shell_INPUT[1024];
    char *tokens[256];
    int tok_counts = 0;

    while(1){

        memset(shell_INPUT,'\0',sizeof(shell_INPUT));

        printf("\n%s@%s: ",getenv("USER"),getenv("SESSION"));
        fgets(shell_INPUT,1024,stdin);

        if((tokens[0] = strtok(shell_INPUT," \n)\t")) == NULL) continue;

        tok_counts = 1;

        while((tokens[tok_counts] = strtok(NULL, " \n\t")) != NULL) tok_counts++;
        /*
        int i=0;
        while(tokens[i]){
            printf("%s ",tokens[i]);
            i++;
        }
        tokens[tok_counts] = NULL;*/
        command_HANDLER(tokens);

    }


    return 0;
}

int fileIO_EXECUTER(char *args[], int in, int pos){
    int fd;
    pid_t pid;

    if((pid=fork())==0){
        switch(pos){

            case 0: 
                    dup2(fd, STDOUT_FILENO);
                    break;


        }
    }
}

int pipe_EXECUTER(char *args[], int in, int pos){

    int fd[2];
    pid_t pid;
    pipe(fd);

    if((pid=fork())==0){
        printf("%s %s %s %d\n",args[0],args[1],args[2],pid);
        fflush(stdout);
        switch(pos){

            case 0: dup2(fd[1], STDOUT_FILENO);     //first command
                    //close(fd[1]);
                    break;

            case 1: dup2(in, STDIN_FILENO);             //in between command
                    dup2(fd[1], STDOUT_FILENO);
                    //close(fd[1]);
                    break;

            case 2: dup2(in, STDIN_FILENO);         //last command
                    //close(fd[1]);
                    break;

            default: printf("wrong input variable\nexiting");
                     exit(1);   

        }
        if(execvp(args[0],args)==-1) printf("%s: command not found",args[0]); fflush(stdout); kill(getpid(),SIGTERM);

    }else if(pid<0){
        printf("couldn't create child");
        exit(1);
    }else{
        wait(pid);
    }

    return fd[0];

}

void command_EXECUTER(char *args[]){

    pid_t pid;

    if((pid=fork())<0){
        printf("couldn't create the child");
        exit(1);
    }
    else if(pid==0){

        if((execvp(args[0],args))==-1) printf("%s: command not found",args[0]); fflush(stdout); kill(getpid(),SIGTERM);
    }
    else wait(pid);

}

void command_HANDLER(char *args[]){

    int i=0;
    int j=0;
    char spec_chars[100];

    while(args[i]){
        if((strcmp(args[i],">")==0) || (strcmp(args[i],"<")==0) || (strcmp(args[i],"|")==0) || (strcmp(args[i],"&")==0) || (strcmp(args[i],"$")==0)){
            spec_chars[j] = *args[i];
            j++;
        }
        i++;
    }

    if(j==0){
        if(strcmp(args[0],"exit")==0) exit(0);
        else if(strcmp(args[0],"clear")==0) system("clear");
        else command_EXECUTER(args);
    }
    else{

        int in = 0;
        int h = 0;
        int pos=0;
        char data[1024];
        int k=i;
        i = 0;
        while(args[i]){
            if(strcmp(args[i],"|")==0){
                args[i] = (char *)NULL;
                in = pipe_EXECUTER(args,in,pos);
                int n = read(in,data,sizeof(data));
                printf("%s %d\n",data,n);
                fflush(stdout);
                args = args+i+1;

                //printf("%s something %s",args[0],args[1]);
                pos = 1;
                i=0;
            }else if(strcmp(args[i],"<")==0){


            }else if(strcmp(args[i],">")==0){

            }else if(strcmp(args[i],"&")==0){

            }
            else{
                i++;
            }

        }
        in = pipe_EXECUTER(args,in,2);
    }

}
#包括
#包括
#包括
#包含//用于pid\u t fork()和其他系统调用
#包括//用于信号()
#包括
void命令执行器(char*args[]);
void命令处理程序(char*args[]);
int pipe_执行器(字符*参数[],int in,int pos);
void shell_INIT(){
int is_interactive=isatty(标准文件号);
如果(是交互式的){
}
}
int main(int argc,char*argv[],char**envp){
字符shell_输入[1024];
字符*标记[256];
int tok_计数=0;
而(1){
memset(shell_输入,'\0',sizeof(shell_输入));
printf(“\n%s@%s:”,getenv(“用户”),getenv(“会话”);
fgets(外壳输入,1024,标准输入);
如果((标记[0]=strtok(shell\u输入,“\n\t”)==空)继续;
tok_计数=1;
而((令牌[tok_计数]=strtok(NULL,“\n\t”))!=NULL)tok_计数++;
/*
int i=0;
while(代币[i]){
printf(“%s”,代币[i]);
i++;
}
令牌[tok_计数]=空*/
命令处理程序(令牌);
}
返回0;
}
int fileIO_执行器(字符*参数[],int-in,int-pos){
int-fd;
pid_t pid;
如果((pid=fork())==0){
开关(pos){
案例0:
dup2(fd,标准文件号);
打破
}
}
}
int pipe_执行器(字符*参数[],int in,int pos){
int-fd[2];
pid_t pid;
管道(fd);
如果((pid=fork())==0){
printf(“%s%s%s%d\n”,参数[0],参数[1],参数[2],pid);
fflush(stdout);
开关(pos){
案例0:dup2(fd[1],STDOUT_FILENO);//第一个命令
//关闭(fd[1]);
打破
案例1:dup2(in,STDIN_FILENO);//中间命令
dup2(fd[1],标准文件号);
//关闭(fd[1]);
打破
案例2:dup2(in,STDIN_FILENO);//最后一个命令
//关闭(fd[1]);
打破
默认值:printf(“错误的输入变量\n输入”);
出口(1);
}
if(execvp(args[0],args)==-1)printf(“%s:未找到命令”,args[0]);fflush(stdout);kill(getpid(),SIGTERM);
}否则,如果(pid
“in”描述符将包含ls,但当相同的输出
通过“排序”访问,它挂在那里

这是由于没有在父进程中关闭管道的写入端而导致的,因为
排序
会自然地等待,直到所有引用写入端的文件描述符都关闭,以确保不再有输入到达。因此,在
管道执行器()
中,必须调用
关闭(fd[1])
在返回fd[0]之前;
当然还有调试代码

                int n = read(in,data,sizeof(data));
                printf("%s %d\n",data,n);

命令中,必须删除HANDLER()
,为了不使用
排序的输入(
gcc-Wall-Wextra-g
),请使用所有警告和调试信息(
gcc-Wall-Wextra-g
)进行编译,然后使用调试器(
gdb
);还要进行故障测试(并在出现故障时使用
peror
)每一个也考虑使用<代码> Struts <代码> Valgnnd/Cuth>实际上我刚开始用这个,不知道如何使用GDB或其他调试工具……如果你可以帮助……谢谢,你需要学习<代码> GDB 。这是一个有用的技能很多年!l gdb、strace和valgrind但仍然没有运气:(有些bug需要几周才能被发现。祝你好运!不要放弃。休息一下,然后继续寻找你的bug。不要忘记阅读你正在使用的每个系统调用的文档。特别是,你使用的
dup2
是错误的:你没有处理
dup2
的故障。另外,在
fork
之前调用
fflush