先搞懂要实现的my_bash是个什么东西,需要什么,需要实现的功能是什么,是怎么样实现的?
这里可以先观察系统本身自带的bash,观察其本身是怎么什么,什么时候需要,什么时候出现等一系列相关情况。
再来对my_bash的实现进行基本的规划,得出大体框架。
再在大体框架下进一步去完善各个模块的内容。
命令的分类:
–内置命令
–cd exit
普通命令:通过which 是可以找到的
例如:ls pwd ps
bash 复制自身,复制出来一个子进程 ,将其替换ps/ls…等所需进程
while(1)
{
printf("stu@stu-vir....");
char buff[128];
fgets(buff); //cp a.c b.c
//分割命令:myargv 改数组的第一个为命令,后面为其他参数
char *cmd = myargv[0];
if(为内置命令){例如: cd 、exit...}
else fork + exec; //为普通命令,例如:ls,ps,cp
}
strtok内部定义了一个指针,专门用来记录刚才分割到哪里;
代码如下:
include <stdio.h>
#include
#include
#include
#include
#define ARG_MAX 10
char *get_cmd(char *buff,char *myargv[])
{
if(buff==NULL||myargv==NULL)
{
return NULL;
}
int i=0;
char *s=strtok(buff," ");
while(s!=NULL)
{
myargv[i++]=s;
s=strtok(NULL," ");
}
return myargv[0];
}
void run_cmd(char *path,char *myargv[])
{
if(path==NULL || myargv==NULL)
{
return ;
}
pid_t pid=fork();
if(pid==-1)
{
return ;
}
if(pid==0)
{
//替换
execvp(path,myargv);
perror("execvp error\n");
exit(0);//子进程必须要退出
}
else
{
wait(NULL);
}
}
int main()
{
while(1)
{
printf("stu@localhost ~$");
fflush(stdout);
char buff[128]={0};
fgets(buff,128,stdin);
buff[strlen(buff)-1]=0;
char *myargv[ARG_MAX]={0};
char *cmd=get_cmd(buff,myargv);
if(cmd==NULL)
{
continue;
}
else if(strcmp(cmd,"cd")==0)
{
}
else if(strcmp(cmd,"exit")==0)
{
break;
}
else//普通命令
{
//fork+exec;
run_cmd(cmd,myargv);
}
}
exit(0);
}
//主要将打印信息的代码prin_info:
完整代码如下:
#include
#include
#include
#include
#include
#include
#define ARG_MAX 10
void print_info()
{
char *user_str="$";
int user_id=getuid();
if(user_id==0)
{
user_str="#";
}
struct passwd*ptr= getpwuid(user_id);
if(ptr==NULL)
{
printf("mybash1.0>> ");
fflush(stdout);
return;
}
char hostname[128]={0};
if(gethostname(hostname,128)==-1)
{
printf("mybash1.0>> ");
fflush(stdout);
return ;
}
char dir[256]={0};
if(getcwd(dir,256)==NULL)
{
printf("mybash1.0>> ");
fflush(stdout);
return ;
}
printf("\033[1;32m%s@%s\033[0m \033[1;34m %s\033[0m%s ",ptr->pw_name,hostname,dir,user_str);
fflush(stdout);
}
char *get_cmd(char *buff,char *myargv[])
{
if(buff==NULL||myargv==NULL)
{
return NULL;
}
int i=0;
char *s=strtok(buff," ");
while(s!=NULL)
{
myargv[i++]=s;
s=strtok(NULL," ");
}
return myargv[0];
}
void run_cmd(char *path,char *myargv[])
{
if(path==NULL || myargv==NULL)
{
return ;
}
pid_t pid=fork();
if(pid==-1)
{
return ;
}
if(pid==0)
{
//替换
execvp(path,myargv);
perror("execvp error\n");
exit(0);//子进程必须要退出
}
else
{
wait(NULL);
}
}
int main()
{
while(1)
{
// printf("stu@localhost ~$");
print_info();
fflush(stdout);
char buff[128]={0};
fgets(buff,128,stdin);
buff[strlen(buff)-1]=0;
char *myargv[ARG_MAX]={0};
char *cmd=get_cmd(buff,myargv);
if(cmd==NULL)
{
continue;
}
else if(strcmp(cmd,"cd")==0)
{
if(myargv[1]!=NULL)
{
if(chdir(myargv[1])==-1)
{
perror("cd err");
}
}
}
else if(strcmp(cmd,"exit")==0)
{
break;
}
else//普通命令
{
//fork+exec;
run_cmd(cmd,myargv);
}
}
exit(0);
}
在这里要注意的就是有关用户信息与主机信息的提取,也就是相关函数的使用;
其实代码写到这里可以算是相关功能已经完全完成了,只不过我们想所有的命令都不
是用的系统自带的命令,那么我们就可以自己写命令:
其实我们会发现,我们前面自己写过kill命令,自己写过cp命令.那么我们自己建立一个
mybin文件,依次实现clear,pwd,ls命令等等…