基于C语言实现MyShell

实现的功能

1.获取命令行

2.解析命令行
3.建立一个子进程
4.替换子进程
5.父进程等待子进程退出

代码如下:

  1 #include <unistd.h>
  2 #include <sys/wait.h>
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include <string.h>
  6 
  7 char *argv[8];
  8 int argc=0;
  9 
 10 void do_parse(char *buf)
 11 {
 12     int i;
 13     int status=0;
 14     for(argc=i=0;buf[i];i++)
 15     {
 16         if(!isspace(buf[i])&&status == 0)
 17         {
 18             argv[argc++]=buf+i;
 19             status=1;
 20         }
 21         else if(isspace(buf[i]))
 22         {
 23             status=0;
 24             buf[i]=0;
 25         }
 26     }
 27     argv[argc]=NULL;
 28 }
 29 
 30 void do_execute(void)
 31 {
 32     pid_t pid=fork();
 33     switch(pid)
 34     {
 35         case -1:
 36         perror("fork");
 37         exit(EXIT_FAILURE);
 38         break;
 39         case 0:
 40         execvp(argv[0],argv);
 41         perror("execvp");
 42         exit(EXIT_FAILURE);
 43         dafault:
 44         {
 45             int st;
 46             while(wait(&st)!=pid)
 47             ;
 48         }
 49     }
 50 }
 51 
 52 int main()
 53 {
 54     char buf[1024]={};
 55     while(1)
 56     {
 57         printf("myshell>");
 58         scanf("%[^\n]%*c",buf);
 59         do_parse(buf);
 60         do_execute();
 61     }
 62 }

在myshell实现输入重定向功能和输出重定向功能,可以使用dup2()函数来实现文件描述符的重定向,下面是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #define MAX_CMD_LEN 256 int main() { char cmd[MAX_CMD_LEN]; char *args[MAX_CMD_LEN]; char *input_file, *output_file; int input_fd, output_fd; int i, j; while (1) { printf("myshell> "); fgets(cmd, MAX_CMD_LEN, stdin); // 读取命令行输入 if (feof(stdin)) { // 用户输入Ctrl+D,退出程序 printf("\n"); break; } // 解析命令行参数 args[0] = strtok(cmd, " \n"); i = 1; while ((args[i] = strtok(NULL, " \n")) != NULL) { i++; } args[i] = NULL; // 查找输入输出重定向符号 input_file = NULL; output_file = NULL; for (j = 0; j < i; j++) { if (strcmp(args[j], "<") == 0) { // 输入重定向符号 input_file = args[j+1]; args[j] = NULL; break; } if (strcmp(args[j], ">") == 0) { // 输出重定向符号 output_file = args[j+1]; args[j] = NULL; break; } } // 执行命令 pid_t pid = fork(); if (pid == -1) { perror("fork"); exit(1); } else if (pid == 0) { // 子进程 // 输入重定向 if (input_file != NULL) { input_fd = open(input_file, O_RDONLY); if (input_fd == -1) { perror("open input file"); exit(1); } if (dup2(input_fd, STDIN_FILENO) == -1) { perror("dup2 input"); exit(1); } close(input_fd); } // 输出重定向 if (output_file != NULL) { output_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (output_fd == -1) { perror("open output file"); exit(1); } if (dup2(output_fd, STDOUT_FILENO) == -1) { perror("dup2 output"); exit(1); } close(output_fd); } // 执行命令 execvp(args[0], args); perror(args[0]); exit(1); } else { // 父进程 waitpid(pid, NULL, 0); } } return 0; } ``` 注意,在解析命令行参数的过程,需要查找输入输出重定向符号,并将其后面的文件名作为重定向的文件。然后,在子进程使用dup2()函数将文件描述符复制到标准输入或标准输出的文件描述符上。最后,关闭不需要的文件描述符。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值