-2

我一直在研究一个通过终端模拟 shell 的 C 程序。我被困在使用临时文件的管道上。

我的问题是,在执行类似命令的过程中,ls | wc它在 10 上运行了 9 次。此外,如果我在终端(真实的,不是我的)中执行此命令,大约 1/10 的时间会收到一条错误消息,表明 wc 命令确实不存在。嗯?

我的代码看起来不错,所以我怀疑错误来自我的 UNIX 设置(终端或核心,我不知道)。但我不确定。这看起来像是代码错误还是操作系统问题?

/**************************************/
/*           test parsing             */
/**************************************/

#include<unistd.h>
#include<stdio.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/types.h>
#include<stdlib.h>
#include<string.h>
#include <errno.h>

char *delimiteurs = ";&<>|";
char *eltsCommande[10];
char *eltsoutput[10];
char *eltsinput[10];
char *eltstube[10];
char mot[50];
int symbole, status, c;

void parsing(){
    int i=0;
    int cmot=0;
    while(1){
        c = getchar();
        if      (c == '\n') {symbole = 0;return;}
        else if (c == ';')  {symbole = 1;return;}
        else if (c == '&')  {symbole = 2;return;}
        else if (c == '<')  {symbole = 3;return;}
        else if (c == '>')  {symbole = 4;return;}
        else if (c == '|')  {symbole = 5;return;}
        else if (c == EOF)  {symbole = 7;return;}
        else if (c != ' ') {
            symbole = 10;
            while(c != '\n' && !strchr(delimiteurs,c)){
                i=0;
                while(c != 32 ){
                    if((c != '\n') && !strchr(delimiteurs,c)){
                    mot[i]=c;i++;
                    c=getchar();
                    }
                    else {break;}
                }
                break;
            }
            while(c == ' ')
            {
                c=getchar();
            }
            ungetc(c,stdin);
            mot[i]=0;
            eltsCommande[cmot++]=strdup(mot);
            fflush(stdout);
            if(c == '\n' || strchr(delimiteurs,c))
            {
                eltsCommande[cmot]=0;
                return;
            }
        }
    }

}

int main(int argc, char* argv[]) {
    pid_t pid, fid;
    int background = 0;
    int status;
    char car;
    int i, j, k, l;
    int p, p2;
    int execute=1;
    int output=0;
    int input=0;
    int tube=0;
    int fd[2];
    int fich;
    while(1){
        if(execute==1){
            if(symbole==0){
                printf("Entrez une commande> ");
            }    
            for (j=0;j<10;j++){
                eltsCommande[j]=NULL;
            }            
            execute=0;    
            background=0;
        }
        fflush(stdout);
        parsing();
        switch (symbole) {
            case 0 :                            // SYMBOLE : \n
                p=fork();
                for(k=0;k<10;k++){
                     printf("ELEMENT COMMANDE %d : %s \n", k, eltsCommande[k]);
                     //printf("ELEMENT COMMANDE TUBE %d : %s \n", k, eltstube[k]);
                     //printf("ELEMENT COMMANDE INPUT %d : %s \n", k, eltsinput[k]);
                     //printf("ELEMENT COMMANDE OUTPUT %d : %s \n", k, eltsoutput[k]);
                }

                if(p==0){                    //fils
                    if(tube==1){//printf("\n\n\n");
                              fich = open("fichtmp",O_RDONLY,0640);
                        close(0); //fermeture clavier
                        dup(fich); //fichier devient entrée 0
                        execvp(eltsCommande[0], eltsCommande);
                        close(fich); //fermeture fichier
                          }
                          else if(output==0 && input==0){        //pas de redirection
                          printf("truc1");
                        execvp(eltsCommande[0], eltsCommande);    
                    }else if(output==1){                //dans le cas d'une redirection
                    printf("truc2");
                        close(1);
                        int filew = creat(eltsCommande[0], 0644);
                        execvp(eltsoutput[0], eltsoutput);
                    }
                    else if(input==1){
                    printf("truc3");
                        close(0);
                        int filer = open(eltsCommande[0], O_RDONLY);
                        execvp(eltsinput[0], eltsinput);
                    }/*
                    if(tube==1){
                        int f2 = fork();
                        pipe(fd);
                        switch (f2){
                        case -1 : printf("loose");
                        case 0: close(fd[0]);
                            close(1);
                            dup(fd[1]);
                            close(fd[1]);
                                 execvp(eltstube[0], eltstube); break;
                               case 1: wait(&status);
                            close(fd[1]);
                            close(0);
                            dup(fd[0]); 
                            close(fd[0]);
                              execvp(eltsCommande[0], eltsCommande); break;
                          default : printf("err");
                          }*/
                    return 0;
                }else{                            //pere
                    if(background==0){                //pas de bg on attend le fils
                        waitpid(p, NULL, 0);
                    }                    
                    /*if(tube==1){
                        close(0);
                                dup(fd[0]);
                               close(fd[1]);
                              execvp(eltsCommande[0], eltsCommande);
                    }*/
                    output=0;
                    input=0;            
                    execute=1;
                    tube=0;
                }
                break;
            case 1:                                // SYMBOLE : ;
                p=fork();                        
                if(p==0){                         //fils
                    if(output==0 && input==0 && tube==0){        //pas de redirection
                        execvp(eltsCommande[0], eltsCommande);    
                    }else if(output==1){                //dans le cas d'une redirection
                        close(1);
                        int filew = creat(eltsCommande[0], 0644);
                        execvp(eltsoutput[0], eltsoutput);
                    }
                    else if(input==1){
                        close(0);
                        int filer = open(eltsCommande[0], O_RDONLY);
                        execvp(eltsinput[0], eltsinput);
                    }
                    return 0;                
                }else{                            //pere
                    waitpid(p, NULL, 0);    
                    output=0;
                    input=0;
                    execute=1;    
                }
                break;
            case 2:                                // SYMBOLE : &
                background=1;
                break;
            case 3:                                // SYMBOLE : <

                      if(input==0){
                          input=1;
                          execute=1;
                          for (l=0;l<10;l++){
                              eltsinput[l]=eltsCommande[l];
                          }
                      }
                      break;
            case 4:                                // SYMBOLE : >
                if(output==0){
                    output=1;
                    execute=1;
                    for (l=0;l<10;l++){
                        eltsoutput[l]=eltsCommande[l];
                    }
                }
                break;
            case 5:                                // SYMBOLE : |
                //if(tube==0){
                    /*for (l=0;l<10;l++){
                        eltstube[l]=eltsCommande[l];
                    }*/
                    p2=fork();
                    if(p2==0){
                        if(tube==0){
                            freopen( "fichtmp", "w", stdout );
                            execvp(eltsCommande[0], eltsCommande);
                        }
                        return(0);
                    }
                    else{    if(background==0){            // SANS MOD BG ATTENDRE FIN FILS
                            waitpid(p2, NULL, 0);
                        }
                        tube=1;                
                        execute=1;    
                    }

                break;
            default: 
                printf("");

        }
    }
    return 0 ;
}
4

1 回答 1

0

我想我是从哪里发现这个问题的。

|我有时会做一个空格,而不是一个Alt Gr + space空格,这不是终端的有效空格。他试图执行(space)wc而不是,wc这就是为什么我得到“找不到命令”。

感谢所有研究过这个问题的人。

于 2012-12-20T09:18:02.767 回答