普通命令:ls 、pwd、cp、clear…(通过exec+fork)
内置命令:cd、exit(bash本身提供方法,调用自己的函数,不会产生子进程)
1.mybash项目里面的实现
#include
#include
#include
#include
#include
#include
#define ARG_MAX 10
#define PATH_BIN "/home/stu/c/test1205/mybin/" //自定义路径
void run_cmd(char* name, char* myargv[]) //系统提供的cp 可执行程序 ls...
{
if(name==NULL||myargv==NULL)return;
int len=strlen(name);
if(name[len-1]=='\n')
name[len-1]=='\0';
pid_t pid=fork();
if(pid==0)//子进程处理 命令 exec
{
//execvp(name,myargv); 使用系统提供的命令 PATH
char pathname[128]={0};
if(strncmp(name,"./",2)==0||strncmp(name,"/",1)==0)
{
strcpy(pathname,name);
}
else //将PATH_BIN + ls
{
strcpy(pathname,PATH_BIN);
strcat(pathname,name);
}
execvp(pathname,myargv);
perror("exec err");
exit(1);
}
wait(NULL);
}
char* get_cmd(char *buff,char* myargv[])
{
if(buff==NULL&&myargv==NULL) return NULL;
char* s=strtok(buff,"");
int i=0;
while(s!=NULL)
{
myargv[i++]=s;
s=strtok(NULL," ");
}
return myargv[0];
}
void printf_info()60 {
char* user_str="$";
int user_id=getuid();
if(user_id==0)user_str="#";
struct passwd* ptr=getpwuid(user_id);
char hostname[128]={0};
gethostname(hostname,128);
char dir[256]={0};
getcwd(dir,256);
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};//输入:pwd ls cp a.c b.c ps -f
fgets(buff,127,stdin); //"pwd\n"
buff[strlen(buff)-1]='\0';
//分隔["cp"]["a.c"]["b.c"]
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&&chdir(myargv[1])==-1)
{
perror("cd err");
}
}
else if(strcmp(cmd,"exit")==0)
{
//exit(0) 程序不会帮我们释放资源
break;
}
else
{
run_cmd(cmd,myargv);
//fork + exec 实现进程替换 pwd ls
}
// sleep(1000);
}
}
2、mybin路径下实现ls、pwd、mkdir、clear、vim、cp 命令
1)clear的实现
#include
#include
#include
int main()
{
printf("\033[2J\033[0;0H");
exit(0);
}
#include
#include
#include
int main()
{
char path[128]={0};
if(getcwd(path,128)==NULL)
{
perror("getcwd err");
exit(1);
}
printf("%s\n",path);
exit(0);
}
#include
#include
#include
#include
#include
#include
int main(int argc,char* argv[])
{
char path[128]={0};
if(getcwd(path,128)==NULL)
{
perror("path err");
exit(1);
}
if(argc!=2)
{
printf("mkdir err\n");
exit(1);
}
if(mkdir(argv[1],S_IXUSR|S_IXGRP|S_IXOTH)==-1)
{
perror("mkdir err\n");
exit(1);
}
exit(0);
}
4)vim的实现
#include
#include
#include
#include
#include
int main(int argc,char* argv[])
{
if(argc!=2)
{
perror("argc err");
}
char* s=argv[1];
int fd=open(s,O_WRONLY|O_CREAT,0600);
if(fd==-1)exit(1);
char buff[128]={0};
while(1)
{
fgets(buff,128,stdin);
if(strncmp(buff,"exit",4)==0)
{
break;
}
dprintf(fd,"%s\n",buff);
}
close(fd);
exit(0);
}
5)cp的实现
#include
#include
#include
#include
int main(int argc,char* argv[])
{
char* s_name=argv[1];
char* new_name=argv[2];
int fdr= open(s_name,O_RDONLY);
char buff[128]={0};
int fdw=open(new_name,O_WRONLY|O_CREAT,0600);
int num=0;
while((num=read(fdr,buff,128))>0)
{
write(fdw,buff,num);
}
close(fdr);
close(fdw);
}
#include
#include
#include
#include
#include
#include
int main(int argc,char* argv[]){
char path[128]={0};
if(getcwd(path,128) == NULL) exit(1);
if(argc!=1&&strncmp(argv[1],"/",1)==0||argc!=1&&strncmp(argv[1],".",1)==0)
{
int len=strlen(argv[1]);
memset(path,0,128);
strncpy(path,argv[1],len-1);
}
else if(argc!=1&&strncmp(argv[1],".",1)!=0)
{
int len=strlen(argv[1]);
strcat(path,"/");
strncat(path,argv[1],len-1);
}
//打开目录流opendir
DIR* pdir = opendir(path);
if(pdir == NULL) exit(1);
struct dirent* s = NULL;
while((s=readdir(pdir)) != NULL){ //读取目录流里面的文件信息(readdir)
if(strncmp(s->d_name,".",1) == 0){
continue;
}
struct stat filestat;
stat(s->d_name,&filestat);//获取当前文件信息 保存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)) { // 000100 & 0000111 -> 0000100 -> 1 true
printf("\033[1;32m%s\033[0m ",s->d_name);
}
else{
printf("%s ",s->d_name);
}
}
}
printf("\n");
closedir(pdir);
exit(0);
}