Linuxの下のプログラムの置換、exec関数の族、およびプログラムの置換を利用して1つの簡単なminishellを実現します

3074 ワード

プログラム置換
プログラム置換とは、実行中のプログラムを置換することである.linuxのプロセスはpcbであり、実行中のプログラムの記述であり、仮想アドレス空間とページテーブルを通じて、プログラムの実行に対応するデータとコードを物理メモリにマッピングし、プログラムの置換はpcbは変わらないが、物理メモリにマッピングされたコードとデータは別のプログラムに変更されることを知っている.
では、プログラムの置き換えをどう理解すればいいのでしょうか.fork()を使用してサブプロセスを作成した後、サブプロセスは親プロセスと同じプログラムを実行します(戻り値によるコードの分流は考慮しません).この場合、サブプロセスでexec関数を呼び出して他のプログラムを実行することができます.このプログラムが問題を起こしても親プロセスに影響を与えません.問題がなければ、他の任務を遂行するのに役立ちます.
exec関数ファミリー関連関数の紹介
execl(char* path, char* arg, ...);
execv(char* path, char* argv[]);

execlp(char* filename, char* arg, ...);
execvp(char* filename, char* argv[]);

execle(char* path, char* arg, ..., char* env[]);
execve(char* filename, char* argv[], char* env[]);
//                  ,            
//       ,          ,   -1

exec関数ファミリーの理解について
  • lとvの区別新プログラムの実行パラメータ付与方式が異なる
     //       ls -l,                        ,   NULL    
     execl("/bin/ls", "ls", "-l", NULL);
     
     //       ls -l,                           ,       NULL      
     char* argv[] = {"ls", "l", "NULL"}
     execv("/bin/ls", argv);
    
  • pの区別の新しいプログラムの名前があるかどうか経路
     // p       
     execlp("ls", "ls", "-l", NULL);
     
     char* argv[] = {"ls", "l", "NULL"}
     execvp("ls", argv);
     //  ,  p          ,        PATH          
    
  • を持つ必要があるかどうか
  • eの区別新しく実行したプログラムが環境変数を再カスタマイズする必要があるかどうか、e付きのカスタム環境変数、eなしで現在のプロセスのデフォルトの環境変数
     //         
     char *env[3] = {NULL};
     env[0] = "MYVAL=1000";
     env[1] = NULL;
    
     execle("ls", "ls", "-l", NULL);
     
     char* argv[] = {"ls", "l", "NULL", env}
     execve("ls", argv, env);
    
  • を使用する
    プログラム置換による簡単なminishellの実現
    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
        while(1) {
            //       shell   
            printf("[MineMinishell]$ ");
            fflush(stdout);//         ,             
            
            //      
            char buf[1024] = {0};
            fgets(buf, 1023, stdin);
            buf[strlen(buf)-1] = '\0'; //                 '\0'
           
            char *argv[32] = {NULL};
            int argc = 0;
            char *ptr = buf;
            
            //              
            while(*ptr != '\0') {
                if (*ptr != ' ') {
                    argv[argc] = ptr;
                    argc++;
                    while(*ptr != ' ' && *ptr != '\0') {
                        ptr++;               
                    }
                    *ptr = '\0';
                }
                ptr++;
            }
            argv[argc] = NULL;//             NULL
            
            //     
            pid_t pid = fork();
            if (pid == 0) {
            	//         
                execvp(argv[0], (char**)argv);//             
                perror("execvp error");//               
                exit(0);
            }
            wait(NULL);//    ,       ,       
        }
        return 0;
    }