进程替换和自己实现一个简单的Shell

目录

1.进程替换的概念

2.了解几个进程替换的接口

3.自己模拟实现一个shell


1.进程替换的概念

我们都明白在创建子进程的时候,子进程会和父进程共用代码。那么如果我们想给子进程单独的代码我们要做什么呢?答案是:我们需要通过调用一些系统接口将子进程替换成新的程序对应的进程。逻辑上就是先将新程序加载入物理内存,再将子进程所对应的页表指向换成该新程序,从而实现进程替换。


2.了解几个进程替换的接口

a.execl(const char* path,const char* argv,......)

path:新程序的路径

argv:指令,例如"ls"

......:选项,例如'-a' '-l'

 如果我们就是想通过进程替换实现ls,实现方法:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 
  4 
  5 int main()
  6 {
  7   execl("/usr/bin/ls","ls","-a","-l",NULL);                                                                                                                             
  8   return 0;
  9 }

结果如下:

 通过进程替换成功实现了ls指令。

b.execlp(const char* file,const char* argv,......)

和execl相比,只是会从path直接找指令,可以直接输入指令名称而非路径。

c.execv(const char* path,const char* argv[])

和execl相比,只是将输入的字符用字符指针数组传入。

d.excvp(const char* file,const char* argv[])

不详细解释了。


3.自己模拟实现一个shell

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

#define NUM 1024
#define SIZE 24
#define EP " "

char cmd_line[NUM];
char *g_argv[SIZE];

int main()
{
  while(1)
  {
  printf("[root@localhost myshell]# "); 
  fflush(stdout);
  memset(cmd_line,'\0',sizeof(cmd_line));
  if(fgets(cmd_line,sizeof(cmd_line),stdin)==NULL)
  {
    continue;
  }
  //清除\n
  cmd_line[strlen(cmd_line)-1]='\0';

  //将输入指令打散 例如 "ls -a -l" -> "ls" "-a" "-l"
  g_argv[0]=strtok(cmd_line,EP);
  int index = 1;
  //美观特殊处理
          if(strcmp(g_argv[0], "ls") == 0)
          {
                        g_argv[index++] = "--color=auto";
                                
          }
          if(strcmp(g_argv[0], "ll") == 0)
          {
                        g_argv[0] = "ls";
                        g_argv[index++] = "-l";
                        g_argv[index++] = "--color=auto";
                                                                
          }
  while(g_argv[index++]=strtok(NULL,EP));
  if(strcmp(g_argv[0], "cd") == 0) //cd 是shell库的函数,内置指令直接调用.
  {
                if(g_argv[1] != NULL)
                chdir(g_argv[1]); //cd path, cd ..
                continue;                                  
  }
  pid_t id = fork();
  if(id == 0)
  {
    printf("下面功能让子进程进行的\n");
    execvp(g_argv[0], g_argv); 
    exit(1);
  }
  int status=0;
  pid_t ret=waitpid(id,&status,0);
  if(ret > 0) printf("exit code: %d\n", WEXITSTATUS(status));
  }   
  return 0;
}

结果如下:

如图所示, 运行myshell后,我们就像正常在shell中使用指令一样。但是还没有实现一些shell库独有的指令,不过基本的都包含在内。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会敲代码的运气选手^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值