Bootstrap

自己编写bash,实现自己的命令

mybash

#include<stdio.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<pwd.h>
#define argc 10
#define PATH "/home/cao/mybash/mybin/"//存放实现自己命令的地址
char* get_cmd(char* buff,char* argv[])
{
    if(buff==NULL||argv==NULL)
    {
        return NULL;
    }//如果参数为0返回空
    char* s=strtok(buff," ");//获取第一个命令
    int i=0;
    while(s!=NULL)
    {
        argv[i]=s;//将命令打入数组
        i++;
        s=strtok(NULL," ");//继续获取剩余参数
    }
    return argv[0];//返回第一个命令
}
void print_info()
{
    char *s ="$";
    int uid=getuid();
    if(uid==0)
    {
        s="#";
    }
    struct  passwd *p=getpwuid(uid);
    if(p==NULL)
    {
        printf("$");
        fflush(stdout);
        return;
    }
    char hostname[128]={0};
    gethostname(hostname,128);

    char curr_dir[256]={0};
    getcwd(curr_dir,256);

    printf("\033[1;34m%s@%s\033[0m \033[1;35m%s\033[0m%s",p->pw_name,hostname,curr_dir,s);
    fflush(stdout);
}
int main()
{
    while(1)
    {
        print_info();
        char buff[128]={0};
        fgets(buff,128,stdin);
        buff[strlen(buff)-1]='\0';
        
        char * argv[argc]={0};
        char* cmd=get_cmd(buff,argv);//cmd是第一个参数,好区别命令和参数
        
        if(cmd==NULL)
        {
            continue;
        }

        else if(strcmp(cmd,"exit")==0)
        {
            break;
        }
        else if(strcmp(cmd ,"cd")==0)
        {
            if( argv[1]!=NULL )
            {
                if( chdir(argv[1]) !=0 )
                {
                    perror("cd err");
                }
            }
        }
        else
        {
        pid_t pid=fork();
        if(pid==-1)
        {
            continue;
        }
        if(pid==0)
        {
            //execvp(cmd,argv);//cmd是命令,argv是后面的参数
            char path[256]={0};
            if(strncmp(cmd,"./",2)==0 || strncmp(cmd,"/",1)==0)//带路径
            {
                strcpy(path,cmd);
            }
            else//不带路径
            {
                strcpy(path,PATH);//先拷贝路径
                strcat(path,cmd);//在链接命令
            }
            execv(path,argv);//  /home/cao/mybash/mybin/
            printf("error\n");
            exit(0);
        }
        }
        wait(0);
    }
    exit(0);
}

pwd实现

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

ls实现

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<dirent.h>
#include<sys/stat.h>
int main()
{
    char path[256]={0};
    getcwd(path,256);

    DIR *p=opendir(path);//打开当前目录流(当前)
    if(p==NULL)
    {
        return 0;
    }

    struct dirent *s=NULL;

    while( (s=readdir(p)) !=NULL)//读目录流,得到一个文件信息
    {
        if(strncmp(s->d_name,".",1)==0)//如果是隐藏文件,则不输出
        {
            continue;
        }
        struct stat st;
        stat(s->d_name,&st);
        if(S_ISDIR(st.st_mode))//判断目录文件
        {
            printf("\033[1;34m%s    \033[0m",s->d_name);//输出蓝色
        }
        else if(S_ISREG(st.st_mode))//判断普通文件
        {
        if(st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH) )//有无执行权限  用户和同组和其他用户相或 如果和结构体相与为一就说明有该权限 
        {
                printf("\033[1;32m%s    \033[0m",s->d_name);//输出绿色
        }
        else    
                printf("\033[1;31m%s    \033[0m",s->d_name);
        }
        else
        { 

        printf("%s     ",s->d_name);

        }
    }
    printf("\n");
    closedir(p);
    exit(0);
}

clear实现

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
    printf("\033[2J\033[0:0H");
    exit(0);
}

;