实现mybash

shell中执行命令的流程bash进程创建一个子进程,然后子进程进程替换,替换成可执行的命令文件。

本质:不断进行fork()+ exec()

实现思路

 

mybash.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <pwd.h>
#define ARG_MAX 10
#define PATH_BIN "/home/stu/dir220/day07/mybin/" //注意,这个路径不能抄,必须是自己的mybin的路径;
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);
char pathname[128]={0};
if(strncmp(path,"/",1)==0|| strncmp(path,"./",2)==0)
{
strcpy(pathname,path);
}
else
{
strcpy(pathname,PATH_BIN);
strcat(pathname,path);
}
execv(pathname,myargv);
perror("execvp error\n");
exit(0);
}
else
{
wait(NULL);
}
}
void printf_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);
}
int main()
{
while(1)
{
printf_info();
// 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)
{
if(myargv[1]!=NULL)//必须保证有第二个参数
{
if(chdir(myargv[1])==-1)
{
perror("cd err");
}
}
}
else if(strcmp(cmd,"exit")==0)
{
// exit(0);//Ok
break;
}
else
{
//fork+exec;
run_cmd(cmd,myargv);
}
}
exit(0);
}

 下面的三个文件放到mybin底下;

clear.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
printf("\033[2J\033[0;0H");
}
//pwd.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
char path[256]={0};
if(getcwd(path,256)==NULL)
{
perror("getcwd error");
exit(1);
}
printf("%s\n",path);
exit(0);
}

 pwd.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
char path[256]={0};
if(getcwd(path,256)==NULL)
{
perror("getcwd error");
exit(1);
}
printf("%s\n",path);
exit(0);
}

 ls.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
int main()
{
char path[256]={0};
if(getcwd(path,256)==NULL)
{
perror("getcwd error");
exit(1);
}
DIR *pdir= opendir(path);
if(pdir==NULL)
{
perror("opendir error");
exit(1);
}
struct dirent *s=NULL;
while((s=readdir(pdir))!=NULL)
{
if(strncmp(s->d_name,".",1)==0)
{
continue;
}
// printf("%s ",s->d_name);
struct stat filestat;
stat(s->d_name,&filestat);
if(S_ISDIR(filestat.st_mode))
{
printf("\033[1;34m%s\033[0m ",s->d_name);//蓝色
}
else
{
if(filestat.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))
{
printf("\033[1;32m%s\033[0m ",s->d_name);
}
else
{
printf("%s ",s->d_name);
}
}
}
printf("\n");
closedir(pdir);
exit(0);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值