使用 fork 和 exec 的简单 shell

Simple shell with fork and exec

我正在尝试从 PATH 中创建一个简单的 shell 运行 任何命令,比如说 ls 或 pwd du gedit 等。我在使用 exec.I 时遇到了问题 require 如果我输入 space 没有任何反应,如果我输入退出它 terminates.Any 感谢帮助

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

#define BUFFER 1024

int main() {
    char line[BUFFER];
    char* args[100];
    char* path = "";
    char program[20];


while(1){
    printf("$ ");
         if(!fgets(line, BUFFER, stdin))
          break;
          size_t length = strlen(line);
         if (line[length - 1] == '\n')
         line[length - 1] = '[=11=]';
     if(strcmp(line, "exit")==0)  break;
         strcpy(program,path);           
         strcat(program,line);
    int pid= fork();              //fork child

        if(pid==0){               //Child
        execlp(program,line,(char *)NULL);    
    }else{                    //Parent
        wait(NULL);
}
}
}   
  1. 您有 2 个 fgets() 通话。去掉第一个fgets(line, BUFFER, stdin);.

  2. 如果缓冲区中有 space,
  3. fgets() 将换行读取。您需要删除它,因为当您输入 exit 时,您实际上会输入 exit\n 并且没有 /bin/exit\n.

  4. 的命令

下面的代码演示了如何删除换行符:

    if(!fgets(line, BUFFER, stdin))
        break;
    char *p = strchr(line, '\n');
    if (p) *p = 0;
  1. 你的用法是错误的。查看execl的手册。您需要传递参数:execl(program, line, (char *)NULL); 注意 NULL 的最后一个参数的转换。如果 NULL 被定义为 0 那么强制转换就变得必要了,因为 execl 是一个可变参数函数。

使用execvp的修改示例:

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

#define BUFFER 1024

int main(void) {
    char line[BUFFER];

    while(1) {
        printf("$ ");
        if(!fgets(line, BUFFER, stdin)) break;
        char *p = strchr(line, '\n');
        if (p) *p = 0;
        if(strcmp(line, "exit")==0) break;
        char *args[] = {line, (char*)0};
        int pid= fork();              //fork child
        if(pid==0) {               //Child
            execvp(line, args);
            perror("exec");
            exit(1);
        } else {                    //Parent
            wait(NULL);
        }
    }

    return 0;
}

您好,请看下面我的更正,也请看我的评论。

int main() {
char line[BUFFER];
char* args[100];
char* path = "/bin/";
char program[20];
char command[50];

while(1){
    printf("$ ");
    if(!fgets(line, BUFFER, stdin))
        break;
    memset(command,0,sizeof(command));
    if(strncmp(line, "exit", (strlen(line)-1))==0)  break;
    strncpy(command,line,(strlen(line)-1));
    strcpy(program, path);
    strcat(program,command);
    int pid= fork();              //fork child
    if(pid==0){               //Child
        execl(program,command,NULL);
        exit(0);// you must exit from the child because now you are inside while loop of child. Otherwise you have to type exit twice to exit from the application. Because your while loop also became the part of every child and from the child again it will call fork and create a child again
    }else{
        wait(NULL);
    }
 }
}

还要支持所有命令执行,请参阅函数 execl 您需要如何在其中传递参数。因此,您需要拆分命令并为 execl.

正确创建参数列表