【Linux】实现简易 bash --- 进程控制(创建,终止,等待),程序替换,内建命令

测试效果

在这里插入图片描述

设置内建命令

在这里插入图片描述

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX 1024
#define ARGV 64


int split_command(char* command, char** argv)
{
  assert(command);
  assert(argv);
  argv[0] = strtok(command, " ");
  if(argv[0] == NULL) return -1;
  int i = 1;
  while((argv[i++] = strtok(NULL, " ")))
  { }
  return 0;
}


void showenv()
{
  extern char** environ;
  int i = 0;
  while(environ[i])
  {
    printf("%d:%s\n", i, environ[i]);
    ++i;
  }

}
//void debug_print(char** argv)
//{
//  for(int i = 0; argv[i]; ++i)
//  {
//    printf("i:%s\n", argv[i]);
//  }
//}

int main()
{
  int last_exit = 0;
  char myenv[32][256];
  int myenv_index = 0;
  while(1)
  {
    char command[MAX] = {0};
    printf("[user@mymachine curpath]# ");
    fflush(stdout);
    char* s = fgets(command, sizeof(command), stdin);
    assert(s);
    (void)s;
    command[strlen(command)-1] = '\0';
    char *argv[ARGV] = {NULL};
    int n = split_command(command, argv);
    if(n != 0) continue;  
    
    if(strcmp(argv[0], "export") == 0)
    {
      if(argv[1] != NULL)
      {
        strcpy(myenv[myenv_index], argv[1]);
        putenv(myenv[myenv_index++]);
      }
      continue;
    }
    if(strcmp(argv[0], "env") == 0)
    {
      showenv();
      continue;
    }
    if(strcmp(argv[0], "echo") == 0)
    {
      const char *target_env = NULL;
      if(*argv[1] == '$')
      {
        if(argv[1][1] == '?')
        {
          printf("%d\n", last_exit);
          continue;
        }
        target_env = argv[1]+1;
      }
      printf("%s=%s\n", argv[1]+1, getenv(target_env));
      continue;
    }
    if(strcmp(argv[0], "ls") == 0)
    {
      int index = 0;
      while(argv[index]) index++;
      argv[index++] = (char*)"--color=auto";
      argv[index] = NULL; 
    }
    if(strcmp(argv[0], "cd") == 0)
    {
      if(argv[1] != NULL) chdir(argv[1]);
      continue;
    }
    //debug_print(argv);
    
    pid_t id = fork();
    assert(id >= 0);
    (void)id;

    if(id == 0)
    {
      execvp(argv[0], argv);
      exit(0);
    }
    //printf("%s\n", command);

    int status = 0;
    pid_t ret = waitpid(id, &status, 0);
    if(ret > 0)
    {
      last_exit = WEXITSTATUS(status);
    }
  
  }

  return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值