> 文章列表 > 【Linux】写一个基础的bash

【Linux】写一个基础的bash

【Linux】写一个基础的bash

头文件

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

分割输入的命令

字符串或参数内容为空则退出

strtok( , )以空格为分隔分割字符串,分割出的第一段赋给p

将分出来的一段装入myargv[]作为参数内容

继续分直到分完为止

将命令名(第一个参数内容)返回

//分割参数
char*get_cmd(char*s,char*myargv[])
{if(s==NULL || myargv==NULL)return NULL;char*p = strtok(s," ");int i=0;while(p!=NULL){myargv[i++]=p;p = strtok(NULL," ");}return myargv[0];
}

打印提示信息

普通成员的提示信息:

【Linux】写一个基础的bash

管理员的提示信息:

【Linux】写一个基础的bash

提示信息需要知道用户名、主机名、路径、提示符样式;

getuid()获取当前用户的id,管理员的uid永远是0,普通成员为其他的。以此区分提示符:$#;

getpwuid(uid)获取用户名;

gethostname( , )获取主机名;

getcwd( , )获取路径;

最后将它们按一定的颜色粗细拼接输出。

//打印提示信息
//查找失败
void find_err(char*s)
{printf("mybash 1.1 %s ",s);fflush(stdout);
}
void printf_info()
{int id = getuid();//提示符char*s="$";if(id==0) s="#";//用户名struct passwd* ptr = getpwuid(id);if(ptr==NULL)//没有得到用户名{find_err(s);return;}char* username = ptr->pw_name;//主机名char hostname[128] = {0};if(gethostname(hostname,128)==-1){find_err(s);return;}//位置char path[128] = {0};if(getcwd(path,128)==NULL){find_err(s);return;}//拼接输出printf("\\033[1;32m%s@%s\\033[0m:\\033[1;34m%s\\033[0m%s ",username,hostname,path,s);fflush(stdout);//刷屏
}

主函数

调用输出提示信息

fgets( , ,stdin )从键盘得到用户输入信息

分割参数

如果输入exit则退出

有些命令需要自己实现

fork()+exec()替换进程

int main()
{while(1){//给一个buff装输入的信息char buff[128] = {0};printf_info();fgets(buff,128,stdin);buff[strlen(buff)-1]=0;//去掉回车//分离参数进myargvchar* myargv[10]={0};char* cmd = get_cmd(buff,myargv);//实现if(cmd == NULL)continue;//如果为空继续if(strcmp(cmd,"exit")==0)break;//退出else if(strcmp(cmd,"cd")==0)//内置命令{if(myargv[1]!=NULL){chdir(myargv[1]);}}else//普通命令{pid_t pid = fork();if(pid==-1)exit(0);if(pid==0){execvp(cmd,myargv);printf("exec err\\n");exit(0);}wait(0);}}exit(0);
}

使用:

【Linux】写一个基础的bash