mybash和pwd,ls函数的实现

strtok(buff," ");对buff中字符串用空格进行分割(第一步)
strtok(NULL," ")剩下的都是传的空

ps,ls这些命令就相当于main.c,是程序员写好的可以直接调用的命令(有执行文件)可以fork替换成它
cd.exit,这些命令是shell内置的命令(无执行文件,是shell自带的命令),因此下面的程序有多个if语句。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/wait.h>wait()的头文件
#include<pwd.h>得到用户信息的头文件
#include<erron.h>perror的头文件
char* get_cmd(char buff[],char* myargv[])对输入的数据进行分割
{
   if(buff==NULL)
   {
      return NULL;
   }
   int i=0;
   char* s=strtok(buff," ");
   while(s!=NULL)
   {
      myargv[i++]=s;
      s=strtok(NULL," ");
   }
   return myargv[0];
}
void printf_info()
{
   printf("\033[1;32mstu@stu-virtual-machile:\033[0m~ $]");用绿颜色显示
   int id=getuid();uid表明那个用户运行了这个进程,管理员的id=0char* s="$";
  if(id==0)
  {
    s="#";
   }
  struct passwd* ptr=getpwuid(id);用户名,用man getpwuid可以查看
  if(ptr==NULL)
  {
     printf("$");
     fflush(stdout);刷屏,会将缓冲区的内容打印在屏幕上
     return;
  }
  char hostname[64]={0};主机名
  if(gethostname(hostname,64)==-1)获取主机名失败
  {
     printf("$");
     fflush(stdout);刷屏,会将缓冲区的内容打印在屏幕上
     return;
  }
  char pwd_buff[128]={0};
  if(getcwd(pwd_buff,128)==NULL)绝对路径
  {
    printf("$");
     fflush(stdout);刷屏,会将缓冲区的内容打印在屏幕上
     return;
  }
  
  printf("\033[1:32m%s@%s %s\033[0m\033[1:34m: %s\033[0m",ptr->pw_name,hostname,pwd_buff,s);s表示是普通用户还是管理员
}
 
int main()
{
   while(1)
   {
      char buff[128]={0};存放从键盘中获取的命令和参数
      //printf("[stu@localhost ~]");
      printf_info();
      fgets(buff,128,stdin);fgets会在输入的数据后面加\n
      buff[strlen(buff)-1]=0;将\n转化为0(\0)
      //ls ,ps ,cp a.txt b.txt 
      char* myargv[10]={0};
      char* cmd=get_cmd(buff,myargv);
      if(cmd==NULL)
      {
        continue;
      }else if(strcmp(cmd,"exit")==0)
      {
         break;//exit(0)
      }else if(strcmp(cmd,"cd")==0)
      {
         if(myargv[1]==NULL)
         {
            continue;
         }
         if(chdir(myargv[1])==-1)出错返回-1
         {
             perror("cd err");打印上一句出错的原因
         }
         continue;
         
      }else
      {
         //fork+exec
         pid_  t pid=fork();
         if(pid==-1)
         {
            printf("fork err\n");
            continue;
         }
         if(pid==0)
         {
            execvp(cmd,myargv);
            printf("execvp err\n");
            exit(0);
         }
         wait(NULL);
      }
   }
}

pwd函数的实现

pwd可以自己实现,也可以fork()+替换通过bash执行实现
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>

iny main()
{
   char buff[128]={0};
   if(getcwd(buff,128)!=NULL)获得当前程序所处的位置,失败返回空
   {
      printf("%s",buff);
   }
}

ls函数的实现

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<dirent.h>目录流获得的结构体头文件


int main()
{
    char buff[128]={0};
    if(getcwd(buff,128)==NULL)
    {
       return 0;如果当前位置获取失败则返回
    }
    DIR* p=opendir(buff);打开目录流
    if(p==NULL)
    {
       return 0;打开失败返回
    }
    struct dirent* s=NULL;
    while((s=readdir(p))!=NULL)读目录流
    {
        if(strncmp(s->d_name,".",1)==0).文件为隐藏文件,如果第一个字符为".",则继续,不打印
        {
            continue;
        }
        printf("%s    ",s->d_name)打印文件名
    }
    printf("\n");
   closedir(p);
   return 0;
}

mybash(不依靠fork)

自己写命令函数,自己给路径

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/wait.h>wait()的头文件
#include<pwd.h>得到用户信息的头文件
#include<erron.h>perror的头文件
#define PATH "/home/stu/c219/day08/mybin/ls"ls函数所放路径

char* get_cmd(char buff[],char* myargv[])对输入的数据进行分割
{
   if(buff==NULL)
   {
      return NULL;
   }
   int i=0;
   char* s=strtok(buff," ");
   while(s!=NULL)
   {
      myargv[i++]=s;
      s=strtok(NULL," ");
   }
   return myargv[0];
}
void printf_info()
{
   printf("\033[1;32mstu@stu-virtual-machile:\033[0m~ $]");用绿颜色显示
   int id=getuid();uid表明那个用户运行了这个进程,管理员的id=0char* s="$";
  if(id==0)
  {
    s="#";
   }
  struct passwd* ptr=getpwuid(id);用户名,用man getpwuid可以查看
  if(ptr==NULL)
  {
     printf("$");
     fflush(stdout);刷屏,会将缓冲区的内容打印在屏幕上
     return;
  }
  char hostname[64]={0};主机名
  if(gethostname(hostname,64)==-1)获取主机名失败
  {
     printf("$");
     fflush(stdout);刷屏,会将缓冲区的内容打印在屏幕上
     return;
  }
  char pwd_buff[128]={0};
  if(getcwd(pwd_buff,128)==NULL)绝对路径
  {
    printf("$");
     fflush(stdout);刷屏,会将缓冲区的内容打印在屏幕上
     return;
  }
  
  printf("\033[1:32m%s@%s %s\033[0m\033[1:34m: %s\033[0m",ptr->pw_name,hostname,pwd_buff,s);s表示是普通用户还是管理员
}
 
int main()
{
   while(1)
   {
      char buff[128]={0};存放从键盘中获取的命令和参数
      //printf("[stu@localhost ~]");
      printf_info();
      fgets(buff,128,stdin);fgets会在输入的数据后面加\n
      buff[strlen(buff)-1]=0;将\n转化为0(\0)
      //ls ,ps ,cp a.txt b.txt 
      char* myargv[10]={0};
      char* cmd=get_cmd(buff,myargv);
      if(cmd==NULL)
      {
        continue;
      }else if(strcmp(cmd,"exit")==0)
      {
         break;//exit(0)
      }else if(strcmp(cmd,"cd")==0)
      {
         if(myargv[1]==NULL)
         {
            continue;
         }
         if(chdir(myargv[1])==-1)出错返回-1
         {
             perror("cd err");打印上一句出错的原因
         }
         continue;
         
      }else
      {
         //fork+exec
         pid_  t pid=fork();
         if(pid==-1)
         {
            printf("fork err\n");
            continue;
         }
         if(pid==0)
         {
            char path[128]={0};
            if(strncmp(cmd,"./",2)==0||strncmp(cmd,"/",1)==0)
            {
                strcpy(path,cmd);
            }else
            {
                strcpy(path,PATH);
                strcat(path,cmd);拼接
            }
            execv(path,myargv);
            printf("execvp err\n");
            exit(0);
         }
         wait(NULL);
      }
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值