c - 在循环中执行多个管道

标签 c linux shell piping

非常接近弄清楚我一直在为用 C 编写的 linux shell 编写的程序。我一直想让它工作一段时间,我决定把它捡起来过去几周一直在修补它。

对于以下代码,请记住称为arrayOfCommands 的数组是动态填充的。我的代码用当前正在运行的命令填充 arrayOfCommands。为了我的示例,我们将运行命令 ls -l | wc 和 arrayOfCommands 填充了以下内容,具体取决于循环的时间:

//Pass #1
arrayOfCommands[]= ("ls", "-l", NULL)

//Pass #2
arrayOfCommands[]= ("wc", NULL)

这是我目前所拥有的:

//PIPING
int do_command(char **args, int pipes) {
    // pipes is the number of pipes in the command
    // (In our example, one)


    // The number of commands is one more than the
    // number of pipes (In our example, two)
    const int commands = pipes + 1;  //Ex: 2
    int i = 0;

    // Set up the pipes
    int pipefds[2*pipes];

    for(i = 0; i < pipes; i++){
        if(pipe(pipefds + i*2) < 0) {
            perror("Couldn't Pipe");
            exit(EXIT_FAILURE);
        }
    }

    // Variables
    int pid;
    int status;
    char *str_ptr;

    int j = 0;
    for (i = 0; i < commands; ++i) {

        // A magic function that updates arrayOfCommands with
        // the current command goes here.  It doesn't make 
        // sense in the context of the code, so just believe me! :)

        // Ex: The contents will be "ls -l" or "wc" depending on 
        // which time through the loop we are

        pid = fork();

        if(pid == 0) {
            //if not last command
            if(i < commands){
                if(dup2(pipefds[j + 1], 1) < 0){
                    perror("dup2");
                    exit(EXIT_FAILURE);
                }
            }

            //if not first command&& j!= 2*pipes
            if(j != 0 ){
                if(dup2(pipefds[j-2], 0) < 0){
                    perror("dup2");
                    exit(EXIT_FAILURE);
                }
            }

            for(i = 0; i < 2*pipes; i++){
                    close(pipefds[i]);
            }

            // Should any of the below inputs be *arrayOfCommands or 
            // **arrayOfCommands or &arrayOfCommands?
            // I'm REALLY bad with pointers

            if( execvp(arrayOfCommands, arrayOfCommands) < 0 ){
                    perror(arrayOfCommands);
                    exit(EXIT_FAILURE);
            }
        }
        else if(pid < 0){
            perror("error");
            exit(EXIT_FAILURE);
        }

        j+=2;
    }

    for(i = 0; i < 2 * pipes; i++){
        close(pipefds[i]);
    }

    for(i = 0; i < pipes + 1; i++){
    }
        wait(&status);
}

当我运行它时,出现了一些错误:

  • dup2:错误的文件描述符
  • ls: |: 没有那个文件或目录
  • ls: wc: 没有那个文件或目录

谁能帮我弄清楚以下两件事:

  1. 为什么会出现这些错误?
  2. 在 execvp 函数中,我在寻找什么样的 if 指针? arrayOfCommands 被初始化为一个 char *arrayOfArgs[]

最佳答案

第一件事:

//if not last command
if(i < commands)

应该是

if(i < commands -1)

因为 i0commands -1 那应该解决 dup2: Bad file descriptor

ls: |: 没有那个文件或目录

ls: wc: 没有那个文件或目录

由格式错误的 arrayOfCommands 引起。它必须被初始化

char * arrayOfCommands[] = {"ls", "-l", NULL};

char * arrayOfCommands[] = {"wc", NULL};

分别通过execvp(arrayOfCommands[0], arrayOfCommands)调用

本质上,arrayOfCommands 的格式必须与 int main(int argc, char** argv) 的参数 vector (通常是 argv)相同

关于c - 在循环中执行多个管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12666152/

相关文章:

linux - Bash:仅允许脚本通过从另一个脚本调用来运行

regex - 提取模式之间的内容

C 编程浅线修复

C Unix 毫秒定时器返回差值 0

c - 当标志是 char 字符串指针而不是 int 时,open() 函数错误

c - 将 x86 程序下面的端口移植到 mips32

c - 使错误 : make (e=2): The system cannot find the file specified

android - 如何制作一个可以通过互联网连接与树莓派通信的Android应用程序?

linux - 升级linux性能

c - 如何用C语言打开nano文件