Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.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_Process_Pipe_Fork - Fatal编程技术网

在c中使用管道执行命令

在c中使用管道执行命令,c,process,pipe,fork,C,Process,Pipe,Fork,我一直在尝试制作一个程序,它可以读取shell命令并像以前一样执行它们 ls -l | sort > there.txt 然而,我所做的似乎并不是在执行第二个命令。 我还是c编程新手,对fork()和pipe()一点都不熟悉,所以如果我所做的有很多错误,我也不会感到惊讶。 如果有人能帮忙,我将不胜感激。 先谢谢你 这是我的密码: 普通的 #include <stdlib.h> #include <stdio.h> #include <string.h>

我一直在尝试制作一个程序,它可以读取shell命令并像以前一样执行它们

ls -l | sort > there.txt
然而,我所做的似乎并不是在执行第二个命令。 我还是c编程新手,对fork()和pipe()一点都不熟悉,所以如果我所做的有很多错误,我也不会感到惊讶。 如果有人能帮忙,我将不胜感激。 先谢谢你

这是我的密码:

普通的

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

void runThat(char* cmd1[], char* cmd2[]);
我也编辑了我的主类,但我测试了它,没有任何问题,所以下面的代码肯定又出了问题。它应该能够在没有管道或多条管道的情况下运行

void runThat(char *cmds[][MAX_PAR], int NOP){
    pid_t pid, waitPid;
    int status;
    int pipefd[2];
    int Num_Cmds = NOP +1;
    int r[Num_Cmds]; int w[Num_Cmds];
    char ** cmd;

    for (int i = 0; i < Num_Cmds; i++){
        r[i] = -1;
        w[i] = -1;
    }

    for (int j = 0; j < NOP; j++){
        pipe(pipefd);
        r[j+1] = pipefd[0];
        w[j] = pipefd[1];
    }

    for (int i = 0; i < Num_Cmds; i++){

        int h = 0;
        while (cmds[i][h]!= NULL){
            cmd[h] = cmds[i][h];
            printf("This [%s]\n", cmd[h]);
            h++;
        }
        cmd[h] = NULL;
        printf("This [%s]\n", cmd[h]);

        if (pid = fork() < 0){
            perror("Fork has failed");
            exit(1);
        }
        else if(pid == 0){
            if (r[i] != -1){
                close(STDIN_FILENO);
                dup2(r[i],STDIN_FILENO);
            }
            if (w[i] != -1){
                close(STDOUT_FILENO);
                dup2(w[i],STDOUT_FILENO);
            }
            for (int j = 0; j < Num_Cmds; j++){
                close(w[j]);
                close(r[j]);
            }
            if (execvp(cmd[0], cmd)==-1){
                perror("Command Failed");
                exit(0);
            }
        }
        else{
            waitPid = wait(&status);
            if (waitPid == -1){
                perror("Waitpid failed");
                exit(1);
            }
            close(w[i]);
            if (i>0){
                close(r[i]);
            }
        }   
    }
}
void runThat(char*cmds[][MAX\u PAR],int NOP){
pid_t pid,waitPid;
智力状态;
int-pipefd[2];
int Num_Cmds=NOP+1;
int r[Num_Cmds];int w[Num_Cmds];
字符**cmd;
对于(int i=0;i0){
闭(r[i]);
}
}   
}
}

(1)我没有看到任何代码可以打开
there.txt
,并将其设置为第二个进程的标准输出。(2) 要构建管道,必须在等待任何进程之前启动所有进程;否则你可能会陷入僵局。(3) 一般来说,对于这样的问题,我们希望看到一个完整的程序,我们可以自己编译、运行和修补。请阅读。这不是您当前的问题,但您没有在第一个子项中关闭足够的管道文件描述符。经验法则:如果使用
dup()
dup2()
将管道的一端重定向到标准输入或输出,则应关闭管道的两端。在某些情况下,您可能不需要这样做,但它们很少。(在本例中这是否重要是另一个讨论。)此外,不需要测试
execvp()
是否失败。如果它返回,则失败。(如果成功,另一个进程正在运行,永远不要返回此代码。)@zwol如果这是一个愚蠢的问题,请原谅我,但我如何真正知道我的进程是否正在运行。这是我到目前为止还没有弄明白的事情…@Sakis当
fork
成功的时候,有两个进程,它们都在运行。@zwol你知道有什么好的来源可以让我读更多关于fork和pipes的书吗?我找到了一些关于C的书,但没有一本是关于C的。
#include "common.h"

#define BUFFER 300


int main(void){

    char * buffer = (char*)malloc(sizeof(char)* BUFFER);
    unsigned int buffer_length;
    char* tkn;
    char * param[BUFFER];
    char * cmd1[BUFFER];
    char * cmd2[BUFFER];
    char *filename = NULL;
    char *output = NULL;
    int append = 0;
    int f1;
    int f2;
    int saved_stdin = dup(0);
    int saved_stdout = dup(1);

    printf("mysh4> ");

    while (1){  
        filename = NULL;
        output = NULL;
        memset(buffer,0,BUFFER);
        int input = getline(&buffer,&buffer_length,stdin);

        if (input==-1){
            printf("\n");
            exit(1);
        }

        if (input>BUFFER){
            printf("Error. Comand must not exceed %d characters.\n",BUFFER);
            exit(1);
        }

        switch(input){
            case 1:
                printf("mysh4> ");
                break;

            default:
                if ((strcmp(buffer,"exit\n")==0)||(strcmp(buffer,"terma\n")==0)||(strcmp(buffer,"end\n")==0)) {
                    printf("EXIT\n");
                    exit(1);
                }
                else {
                    int i =0; int j=0;
                    tkn = strtok(buffer," \t\n");
                    int NOP = 0;
                    while (tkn != NULL){
                        if(strcmp(tkn,"<")==0){
                            filename = tkn = strtok(NULL," \t\n");
                        }
                        else if(strcmp(tkn,">")==0){
                            output = tkn = strtok(NULL," \t\n");
                            append =0;
                        }
                        else if(strcmp(tkn,">>")==0){
                            output = tkn = strtok(NULL," \t\n");
                            append =1;
                        }
                        if(strcmp(tkn,"|")==0){
                            NOP++;
                            //param[i++] = NULL;    
                        }
                        //else
                            param[i++] = tkn; 
                        tkn = strtok(NULL, " \t\n");    
                    }
                    param[i] = NULL;
                    i=0; j=0;
                    while (param[i]!= NULL){
                        if (strcmp(param[i],"|")==0) break;
                        cmd1[i] = param[i];
                        i++;
                    }

                    cmd1[i] = NULL;

                    while (param[i]!=NULL){
                        if (strcmp(param[i],"|")==0) i++;
                        cmd2[j] = param[i];
                        j++; i++;
                    }
                    cmd2[j] = NULL;

                    i=0;
                    while (cmd1[i]!=NULL){
                        printf("cmd1 HAS:[%s]\n", cmd1[i++]);               // TO BE DELETED
                        if (cmd1[i]==NULL){
                            printf("cmd1 HAS:[NULL]\n");
                        }
                    }

                    i=0;
                    while (cmd2[i]!=NULL){
                        printf("cmd2 HAS:[%s]\n", cmd2[i++]);               // TO BE DELETED
                        if (cmd2[i]==NULL){
                            printf("cmd2 HAS:[NULL]\n");
                        }
                    }

                    printf("FILENAME :[%s]\n", filename);
                    printf("OUTPUT: [%s]\n", output);

                    if (filename){
                        f1 = open(filename,O_APPEND | O_RDONLY);
                        if(dup2(f1,0) < 0) {
                            perror("Dup2:Input failed."); exit(1);
                        }
                        close(f1);
                    }

                    if (output){
                        if(append == 0)
                            f2 = open(output,O_WRONLY | O_CREAT | O_TRUNC, 0777);//TRUNC:ta sbhnei
                        else
                            f2 = open(output,O_WRONLY | O_CREAT | O_APPEND, 0777);
                        if(dup2(f2,1) < 0) {
                            perror("Dup2:Output failed."); exit(1);
                        }               
                        close(f2);
                    }

                    runThat(cmd1,cmd2);

                    dup2(saved_stdin,0);    
                    dup2(saved_stdout,1);   

                    printf("mysh4> ");
                    break;


                }//else

        }//switch
    }//while

    free(buffer);
    return 0;
}
total 40
-rw-rw-r-- 1 csuser csuser  1553 Μάι  12 18:27 common.c
-rw-rw-r-- 1 csuser csuser   313 Μάι  12 17:00 common.h
-rwxrwxr-x 1 csuser csuser 12204 Μάι  12 18:25 m
-rw-rw-r-- 1 csuser csuser  2534 Μάι  12 18:00 mysh4.c
-rw-rw-r-- 1 csuser csuser  7395 Μάι  12 12:44 p3090278-mysh4.c
-rwxrwxr-x 1 csuser csuser    59 Μάι  12 17:46 that
-rwxrwxr-x 1 csuser csuser    22 Μάι  12 18:13 there
csuser@CSLAB2:~/Desktop$ total 40
-rw-rw-r-- 1 csuser csuser  1553 Μάι  12 18:27 common.c
-rw-rw-r-- 1 csuser csuser   313 Μάι  12 17:00 common.h
-rwxrwxr-x 1 csuser csuser 12204 Μάι  12 18:25 m
-rw-rw-r-- 1 csuser csuser  2534 Μάι  12 18:00 mysh4.c
-rw-rw-r-- 1 csuser csuser  7395 Μάι  12 12:44 p3090278-mysh4.c
-rwxrwxr-x 1 csuser csuser    59 Μάι  12 17:46 that
-rwxrwxr-x 1 csuser csuser    22 Μάι  12 18:13 there
void runThat(char *cmds[][MAX_PAR], int NOP){
    pid_t pid, waitPid;
    int status;
    int pipefd[2];
    int Num_Cmds = NOP +1;
    int r[Num_Cmds]; int w[Num_Cmds];
    char ** cmd;

    for (int i = 0; i < Num_Cmds; i++){
        r[i] = -1;
        w[i] = -1;
    }

    for (int j = 0; j < NOP; j++){
        pipe(pipefd);
        r[j+1] = pipefd[0];
        w[j] = pipefd[1];
    }

    for (int i = 0; i < Num_Cmds; i++){

        int h = 0;
        while (cmds[i][h]!= NULL){
            cmd[h] = cmds[i][h];
            printf("This [%s]\n", cmd[h]);
            h++;
        }
        cmd[h] = NULL;
        printf("This [%s]\n", cmd[h]);

        if (pid = fork() < 0){
            perror("Fork has failed");
            exit(1);
        }
        else if(pid == 0){
            if (r[i] != -1){
                close(STDIN_FILENO);
                dup2(r[i],STDIN_FILENO);
            }
            if (w[i] != -1){
                close(STDOUT_FILENO);
                dup2(w[i],STDOUT_FILENO);
            }
            for (int j = 0; j < Num_Cmds; j++){
                close(w[j]);
                close(r[j]);
            }
            if (execvp(cmd[0], cmd)==-1){
                perror("Command Failed");
                exit(0);
            }
        }
        else{
            waitPid = wait(&status);
            if (waitPid == -1){
                perror("Waitpid failed");
                exit(1);
            }
            close(w[i]);
            if (i>0){
                close(r[i]);
            }
        }   
    }
}