1. ホーム
  2. c

[解決済み] C 言語で fork/execvp を使って簡単なシェルを作成する

2022-03-01 15:22:16

質問

システムコールのfork()/execvp()を使って、C言語で簡単なシェルを開発する必要があります。今のところ、私のコードはコマンドを受け取り、strtokを使用して配列argvに分割し、それから私は子プロセスを作成し、コマンドを実行するためにforkを呼び出します。私は、ほとんどのコマンドが/bin/ディレクトリにあるubuntuでこれに取り組んでいるので、私はプログラム名(例えば/bin/ls)を追加し、execvpの最初の引数にそれを使用して、私はそれをargv配列に与えます。私のプログラムは、コマンド "ls" を入力すると動作しますが、他のコマンドや "ls -l" を試すと、 "ls: invalid option." が表示されます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_LEN 1024

int main(){
    char line[BUFFER_LEN];  //get command line
    char* argv[100];        //user command
    char* path= "/bin/";    //set path at bin
    char progpath[20];      //full file path
    int argc;               //arg count

while(1){

    printf("My shell>> ");                    //print shell prompt

        if(!fgets(line, BUFFER_LEN, stdin)){  //get command and put it in line
        break;                                //if user hits CTRL+D break
    }
    if(strcmp(line, "exit\n")==0){            //check if command is exit
        break;
    }

    char *token;                  //split command into separate strings
    token = strtok(line," ");
    int i=0;
    while(token!=NULL){
        argv[i]=token;      
        token = strtok(NULL," ");
        i++;
    }
    argv[i]=NULL;                     //set last value to NULL for execvp

    argc=i;                           //get arg count
    for(i=0; i<argc; i++){
        printf("%s\n", argv[i]);      //print command/args
    }
    strcpy(progpath, path);           //copy /bin/ to file path
    strcat(progpath, argv[0]);            //add program to path

    for(i=0; i<strlen(progpath); i++){    //delete newline
        if(progpath[i]=='\n'){      
            progpath[i]='\0';
        }
    }
    int pid= fork();              //fork child

    if(pid==0){               //Child
        execvp(progpath,argv);
        fprintf(stderr, "Child process could not do execvp\n");

    }else{                    //Parent
        wait(NULL);
        printf("Child exited\n");
    }

}
} 

解決方法は?

無効なオプションは fgets() を保持します。 '\n' Enterキーを押したとき、次のようにします。

if(!fgets(line, BUFFER_LEN, stdin))
    break;
size_t length = strlen(line);
if (line[length - 1] == '\n')
    line[length - 1] = '\0';

を呼び出そうとしたとき ls -l を渡すと "-l\n" をオプションとして指定したため、このようなメッセージになりました。

を変更する必要があります。

strcmp(line, "exit\n")

になります。

strcmp(line, "exit")