1

我实际上是在尝试在 C 中实现一个基本的 minishell。为此,我创建了一个函数来解析用户在控制台中输入的内容。我解析了它,然后我想使用管道将命令发送到控制台。我不明白为什么我的管道不工作。我检查了解析,它似乎很好,我在函数的参数中有正确的命令。问题是我的管道代码实际上什么也没做,我不明白为什么。这是我的代码。先感谢您。

#define READ 0
#define WRITE 1

char *cmds[5] = {0};

int main() {    
    char *saisie = (char*)malloc(100*sizeof(char*));
    char *saisie2 = (char*)malloc(100*sizeof(char*));
    gets(saisie);
    int ncmds = 0;
    int k = 0;

    char* token = (char*)malloc(100*sizeof(char*));
    char* tofree;

    if(*(saisie + 0) == '$'){
        if(*(saisie + 2) == 'e' && *(saisie + 3) == 'x' && *(saisie + 4) == 'i' || *(saisie + 5) == 't'){
            exit(0);
        }
        else{
            int i;
            for(i = 0;i<99;i++){
                *(saisie2+i) = *(saisie+i+1);
            }       
            free(saisie);

            if (saisie2 != NULL) {
                tofree = saisie2;

                while ((token = strsep(&saisie2, "|")) != NULL){
                     cmds[ncmds] = token;
                     ncmds++;
                }
                free(tofree);           
            }
        }
    }

    exe(cmds, ncmds);   
    while(wait(NULL) > 0);
    return 0;
}

int exe(char *cmds[], int ncmds){
    int fdin, fdout;
int fds[2];
int i;
int status;
fdin = 0;
for(i=0; i < ncmds-1; i++){
    pipe(fds);
    fdout = fds[WRITE];

    if(fork() == 0){
        if( fdin != 0 ) {
            close(0);
            dup(fdin); 
            close(fdin);
        }
        if( fdout != 1 ) {
            close(1);
            dup(fdout); 
            close(fdout);
        }
        close(fds[READ]);
        const char* prog2[] = {cmds[i], "-l", 0};
        execvp(cmds[i], prog2);
        fprintf(stderr, "si esto se ve es un error\n");
        exit(1);
    }

    if(fdin != 0)
        close(fdin);
    if(fdout != 1)
        close(fdout);

    fdin = fds[READ];
}

/* Ultimo comando */
fdout = 1;
if(fork() == 0) {
    if( fdin != 0 ) {
        close(0); 
        dup(fdin); 
        close(fdin);
    }
    const char* prog2[] = {cmds[i], "-l", 0};
    execvp(cmds[i], prog2);
    close(fds[READ]);
    exit(1);
}

if(fdout!= 1)
    close(fdout);
if(fdin != 0)
    close(fdin);

    }
}
4

1 回答 1

2
int exe(char *cmds[], int ncmds){
    int p2c[2];//pipe parent to child
    int c2p[2];//pipe child to parent
    int i;
    int status;
    int pid;
    char buf[4096];
    memset(buf, 0, 4096);

    for(i=0; i < ncmds; i++){
        pipe(p2c);
        pipe(c2p);

        pid = fork();
        if(pid < 0) {
            exit 1;
        }
        if(pid == 0){ //in child
            close(1);
            dup2(c2p[1],1); // make child write to c2p pipe instead of stdout
            close(0);
            dup2(p2c[0],0); // make child read from p2c pipe instead of stdin
            close(p2c[1]);
            close(c2p[0]);
            const char* prog2[] = {cmds[i], "-l", 0};
            execvp(cmds[i], prog2);
            fprintf(stderr, "si esto se ve es un error\n");
            exit(1);
        }
        //in parent
        write(p2c[1], buf, strlen(buf)); //write the last output to child
        close(p2c[1]);
        close(c2p[1]);
        memset(buf,0,4096);
        if(read(c2p[0], buf, 4096) > 0){ //read output from child
            if(i == ncmds -1 ){
                printf("result:\n");
                printf("%s\n", buf);
            }
        }
    }
}
于 2013-06-13T03:03:03.907 回答