网站内容结构,wordpress伪静态设置方法,电子版邀请函制作软件免费,黑龙江门户网站建设#x1f436;博主主页#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️#x1f525;专栏系列#xff1a;线性代数#xff0c;C初学者入门训练#xff0c;题解C#xff0c;C的使用文章#xff0c;「初学」C #x1f525;座右铭#xff1a;“不要等到什么都没有了#xff0c;才下… 博主主页ᰔᩚ. 一怀明月ꦿ ❤️专栏系列线性代数C初学者入门训练题解CC的使用文章「初学」C 座右铭“不要等到什么都没有了才下定决心去做” 大家觉不错的话就恳求大家点点关注点点小爱心指点指点 感觉有很久都没有写博客主要是最近学的内容难以理解所以时间不太充足就没有写博客的时间今天为什么要这一篇文章呢主要是我感觉实现一个自己的命令行小程序还是比较有趣的。 我们平时都是在linux的shell命令行上直接输入指令有没有想过自己也可以去实现一个自己的bash呢 那就让我们一起来探索属于自己自己的bash 这次我就直接给出源代码没有把其中的方法单独拿出来分析我主要觉得那样有点显得代码冗余其实也不用担心看不懂我在源码中加了很多注释大家也不怕看不懂。其实这样做还有一个好处就是我们可以直接复制到我们的linux文件中直接运行。 源码 #includestdio.h
#includestdlib.h
#includestring.h
#includeunistd.h
#includesys/types.h
#includesys/wait.h#define SIZE 100 //用于定义命令的最大长度
#define NUM 1024 //用于定义命令参数的最多个数
#define SEP //分割字符的时候默认以空格作为分隔符char _cwd[1024]; //用于存储PWD的环境变量
char env_val[1024]; //用于自定义一个环境变量,这里有一个缺点就是env_val是一个数组只能添加一个自定义的环境变量下次添加时就会覆盖上次添加的环境变量
int lastcode0; //用于定义最近一个进程的退出码//获取用户名字
const char* getUsername(void)
{const char* namegetenv(HOME);//getenv如果没有获取到环境变量会返回空值if(name)return name;else return none;
}//获取主机名字
const char* getHostname(void)
{const char* hostgetenv(HOSTNAME);if(host)return host;else return none;
}//获取工作目录
const char* getCwd(void)
{const char* cwdgetenv(PWD);if(cwd)return cwd;else return none;
}//获取用户输入的命令
int getUserCommand(char* usercommand,int num)
{char* rfgets(usercommand,num,stdin);if(rNULL)return -1;usercommand[strlen(usercommand)-1]\0;return strlen(usercommand);
}//分割字符串
int commandSplist(char* usercommand,char* argv[])
{int argc0;argv[argc]strtok(usercommand,SEP);while(argv[argc]strtok(NULL,SEP));return 0;
}//执行命令
int execute(char* argv[])
{pid_t idfork();if(id0)return -1;else if(id0){//childexecvp(argv[0],argv);//程序替换exit(1);//程序替换失败返回1}else{//fartherint status0;//保存子进程退出时的退出码和退出信号pid_t ridwaitpid(id,status,0);//阻塞等待if(rid0)lastcodeWEXITSTATUS(status);//获取子进程退出时的退出码}return 0;
}//改变工作路径
void cd(const char* path)
{chdir(path);//改变工作路径//虽然路径改了但是环境变量中PWD存储的工作路径并没有改变char temp[1024];getcwd(temp, sizeof(temp));sprintf(_cwd, PWD%s,temp);putenv(_cwd);//为什么这里putenv[temp]因为temp是一个临时变量putenv只是将temp这个指针放到环境变量体系中当函数调用结束指针就销毁了这个工作路径的环境变量就访问不了了}//什么叫做内建命令内建命令就是bash自己执行的类似于自己内部的一个函数
//1.是内建命令 0不是内建命令
//执行的是内建命令
int doBuildin(char* argv[])
{if(strcmp(argv[0],cd)0)//cd命令{char* pathNULL;if(argv[1]NULL)path.;elsepathargv[1];cd(path);return 1;}else if(strcmp(argv[0],export)0)//export命令{if(argv[1]NULL)return 1;strcpy(env_val,argv[1]);putenv(env_val);return 1;}else if(strcmp(argv[0],echo)0)//echo命令{char val_0*argv[1];char* valargv[1]1;//argv[1]1:例如$ 则argv[1]是$ argv[1]1是if(val_0$strcmp(val,?)0)//我们定义?保存着最近一个进程的退出码{printf(%d\n,lastcode);lastcode0;}else if(val_0$){printf(%s\n,getenv(val));//打印环境}else//echo打印字符{printf(%s\n,argv[1]);}return 1;}else{//可以添加其他的内建命令}return 0;
}int main()
{while(1){char usercommand[SIZE];//存储用户输入的命令char* argv[NUM];//存储命令行参数//打印命令行提示符printf([%s%s %s]$,getUsername(),getHostname(),getCwd());//输入命令int ngetUserCommand(usercommand, sizeof(usercommand));if(n0)continue;//分割字符commandSplist(usercommand, argv);//判断是否是内建命令ndoBuildin(argv);if(n1)continue;//执行命令execute(argv);}return 0;
}如果大家还有不懂或者建议都可以发在评论区我们共同探讨共同学习共同进步。谢谢大家