Linux7.31 day11 mybash

bash 命令解释器 让系统与用户交互

1.内置命令 cd bash 直接实现 -> 调用函数实现
2.普通命令 fork + exec()

bash基本功能步骤:
1 bash 打印提示信息 [stu@localhost tmp]$
2 fgets(buff) //用户输入数据 ls, cp a.c b.c ,ps -f
3 解析命令 “cp”“a.c” “b.c”
4 判断是内置命令 还是普通命令
5 执行命令 1)直接调用函数 (内置)
2)fork + exec(cp,“a.c”,“b.c”) (普通)
6 wait(); (普通)

mybash里所有命令存放位置 /mybash/mybin

(mybash.c)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <pwd.h>

#define PATH "/home/stu/c215/mybash/mybin/"
#define MAX_ARG 10
void print_info()
{
    char * s = "$";
    int id = getuid();
    if(0 == id)
    {
         s = "#";
    }
    struct passwd* pw = getpwuid(id);
    if(NULL == pw)
    {
         printf("mybash>>$");
         fflush(stdout);
         return;
    }
    
    char hostname[128] = {0};
    if(gethostname(hostname,128) == -1)  //获取主机名
    {
        printf("mybash>>$");
        fflush(stdout);
        return;
    }

    char pwd_str[256] = {0};
    if(getced(pwd_str,256) == NULL)  //获取当前位置
    {
         printf("mybash>>$");
         fflush(stdout);
         return;
    }

    printf("\033[1;32m%s@%s\033[0m \033[1; 34m%s%s\033[0m ",pw>>pw_name,hostname,pwd_str,s);
    fflush(stdout);
}

char * get_cmd(char* buff,char* myargv[])
{
     if(p == 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 change_dirent(char* dir)  //对cd进行封装
{
     if(dir ==NULL)
     {
          return;
     }

     if(chdir(dir) == 1)
     {
          perror("cd err");
     }
}
int main()
{
    while(1)
    {
         print_info();  //打出提示符  获取信息

         char buff[128] = {0};   //从键盘获取命令
         fgets(buff,128,stdin);  //  "ls\n"
         buff[strlen(buff)-1] = 0;  //"ls"

         char* myargv[MAX_ARG] = {0};  //对命令解析后存入myargv
        
         char* cmd = get_cmd(buff,myargv);   //对命令的解析
         if(cmd == NULL)
         {
                continue;
         }
         else if(strcmp(cmd,"cd") == 0)
         {
                change_dirent(myargv[1]);
                continue;
         }
         else if(strcmp(cmd,"exit") == 0)
         {
                break;
         }
         else
         {
                //foek+exec
               pid_t pid = fork();   //复制
               if(pid == -1)
               {
                    printf("fork err\n");
                    continue;
               }
               if(pid == 0)
               {
                    char cmdpath[128] = {0};
                    if(strncmp(cmd,"./",2) != 0 && strncmp(cmp,"/",1) !=0)
                    {
                         strcpy(cmdpath,PATH);
                         strcat(cmdpath,cmd);  //拼接路径  a
                    }
                    else
                    {
                         strcpy(cmdpath,cmd);  //   ./a  /home/stu/a
                    }

                    execv(cmdpath,myargv);  // cmdpath路径加名称
                    //execvp(cmd,myargv);  // 替换 自动去环境变量path下寻找
                    perror("execvp err");
                    exit(0);
               }

               wait(NULL);
         }
    }
}

(pwd.h)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    char path[256] = {0};
    getcwd(path,256);
    printf("%s\n",path);
}

opendir函数
打开一个目录建立一个目录流

(ls.c)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>

int main()
{
    char path[256] = {0};
    if(gercwd(path,256) == NULL)
    {
         printf("ls err:无法得到当前位置");
         exit(0);
    }

    DIR * ptr = opendir(path);
    if(ptr == NULL)
    {
        printf("无法打开目录流\n");
        exit(0);
    }

    struct stat st;
    struct dirent * p = NULL;
    while((p = readdir(ptr)) != NULL)
    {
        if(strncmp(p->d_name,".",1) == 0)
        {
            continue;
        }

        lstat(p->d_name,&st);
        if(S_ISDIR(st.st-_mode))
        {
            printf("\033[1;34m%s   \033[0m",p->d_name);
        }
        else
        {
            if(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
            {
                printf("\033[1;32m%s   \033[0m",p->d_name);
            }
            printf("%s ",p->d_name);  //d_name为文件名
        }
    }

    printf("\n");
    closedir(ptr);
    exit(0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值