1

Cで書かれたLinuxシェル用に書いていたプログラムを理解するのに非常に近づいています。これをしばらく機能させたいと思っていたので、もう一度取り上げることに決め、過去にいじっていました。数週間。

次のコードでは、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: そのようなファイルまたはディレクトリはありません

誰かが次の2つのことを理解するのを手伝ってくれませんか:

  1. これらのエラーが発生するのはなぜですか?
  2. execvp 関数では、どのようなポインタを探していますか? arrayOfCommands は char *arrayOfArgs[] として初期化されました
4

1 に答える 1

3

初めにすること:

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

する必要があります

if(i < commands -1)

dup2: Bad file descriptor を解決する必要i0ありますcommands -1

ls: |: そのようなファイルまたはディレクトリはありません

ls: wc: そのようなファイルまたはディレクトリはありません

不正な形式が原因 arrayOfCommandsです。によって初期化する必要があります

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

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

それぞれ、経由で呼び出されますexecvp(arrayOfCommands[0], arrayOfCommands)

基本的arrayOfCommandsに、 の引数ベクトル (通常はargv)と同じ形式である必要がありますint main(int argc, char** argv)

于 2012-10-01T00:11:44.807 に答える