wordpress多站,凡客诚品下载,seo整站网站推广优化排名,网址大全是什么浏览器#x1f381;个人主页#xff1a;我们的五年
#x1f50d;系列专栏#xff1a;Linux课程学习
#x1f337;追光的人#xff0c;终会万丈光芒
#x1f389;欢迎大家点赞#x1f44d;评论#x1f4dd;收藏⭐文章 目录
打印命令行提示符#xff08;PrintCommandLin…个人主页我们的五年
系列专栏Linux课程学习
追光的人终会万丈光芒
欢迎大家点赞评论收藏⭐文章 目录
打印命令行提示符PrintCommandLine
1.USER和LOGNAME用户名
2.HOSTNAME和PWD
获取命令行信息GetCommadLine
读取时处理换行符
解析命令行ParseCommandLine
执行命令ExecuteCommand
哪些命令可以让子进程执行哪些命令不能让子进程执行为什么
通过getcwd获取实时的cwd通过putenv导入环境变量
myshell维护自己的环境变量 1.我们让子进程执行cd ..命令的时候为什么我们执行pwd命令的时候还是和之前一样路径没有变化
本质就是我们更改的是子进程的环境变量pwd没有改变父进程的。当执行pwd时这个进程的环境变量还是由父进程来的。而父进程的环境变量没有改变所以pwd出来的结果也没有改变。
2.环境变量是由shell自己维护的。
3.在这个简易版shell中我们没有维护这个环境变量还是依靠系统的环境变量。当环境没有修改用的还是系统的环境变量更改时才写时拷贝。
4.echo命令也是内键命令因为子进程不会继承父进程的本地环境变量。所以要打印本地变量只有由shell来做。
打印命令行提示符PrintCommandLine
启动shell程序就是创建-bash进程本质就是一个进程。
首先看到命令行的提示符是这样的 [kymhcss-ecs-32c9 2024-11-26]$ 包括 1.用户名。2.主机名。3.当前的路径。4.命令行提示符。$ 1.USER和LOGNAME用户名 LOGNAME USER和LOGNAME都与当前用户有关但LOGNAME是POSIX标准的一部分更加标准化和一致所以更推荐用LOHNAME确定当前的用户的登录身份。 USER USER的环境变量可能在某些系统中与LOGNAME有相同的值但因为其行为不一致在精确用户身份的时候应该慎用。 2.HOSTNAME和PWD
通过环境变量获取这些信息。
三个函数获得用户信息GetLOGNAME主机信息GetHOSTNAME当前路径信息GetPWD。
通过string进行传递如果要谁用c语言的字符串就通过c_str()进行获得底层char。 头文件 #include stdio.h 函数原型 int sprintf(char *str, const char *format, ...);int snprintf(char *str, size_t size, const char *format, ...); 将这些输入到一个字符串中。 const size_t basesize1024;//获取用户名信息string GetLOGNAME(){string log_namegetenv(LOGNAME);return log_name.empty()?None:log_name;}//获取当前主机信息string GetHSOTNAME(){string host_namegetenv(HOSTNAME);return host_name.empty()?None:host_name;}//获取当前路径信息string GetPWD(){ string pwdgetenv(PWD); if(pwd.empty()) return None; string separator/; string sub_strpwd.substr(pwd.find_last_of(separator)1); return sub_str; }//生成command_line字符串 string MakeCommandLine() {//[kymhcss-ecs-32c9 2024-11-26]$ char command_line[basesize]; snprintf(command_line,basesize,[%s%s %s],\GetLOGNAME().c_str(),\ GetHSOTNAME().c_str(),\GetPWD().c_str());return command_line;}// //1.打印命令行提示符void PrintCommandLine(){printf(%s,MakeCommandLine().c_str());fflush(stdout);}获取命令行信息GetCommadLine
bool GetCommandLine(char command_buff[],size_t size)
{char* resultfgets(command_buff,size,stdin);if(resultNULL)return false;result[strlen(result)-1]0;return true;
}读取失败返回false读取成功把换行符覆盖。
读取时处理换行符
如果我们以一行来读取字符串那么最会就有换行符换行符也会读取进来。所以打印的时候我们没有加换行也是来到了新的一行。
解决办法
在返回前把\n置为0。
result[strlen(result)-1]0; 解析命令行ParseCommandLine
通过strtok函数进行分解字符串。 #include string.h char *strtok(char *str, const char *delim); bool ParseCommandLine(char command_buff[],int len)
{ (void)len; argc0; //初始化 memset(argv,0,sizeof(argv)); const char* sep ; argv[argc]strtok(command_buff,sep); while((bool)(argv[argc]strtok(nullptr,sep))); argc--; return false;
}
sep表示分隔符用来把字符串进行分解。但是在分解之前我们需要把argc和argv进行初始化。每次执行新的命令。
strtok函数第一次调用的时候str指向要分割的字符串。在后续的调用中传NULL。因为strtok函数内部有静态变量维护当前字符串的位置。 执行命令ExecuteCommand
通过子进程发生程序替换。当id0表示子进程。如果发生了程序替换还执行了原来的exit就表示发生错误。然后就是父进程子进程。
bool ExecuteCommand()
{ pid_t idfork(); if(id0) return false; if(id0) { execvp(argv[0],argv); exit(1); } int status0; pid_t ridwaitpid(id,status,0); if(rid0) { //等待失败 } else { return true; } return false;
} 哪些命令可以让子进程执行哪些命令不能让子进程执行为什么 让shell去执行的命令叫做内键命令。 当执行cd命令时为什么pwd没有改变
我们写的超简易版shell中让子进程去执行cd .. 。但是其他的进程不是由子进程产生的不会继承子进程的环境变量还是去继承父进程的环境变量。虽然在子进程中改了环境变量但是没有得到进程所以不起作用。在真正的shell中就是要去改变shell的环境变量。因为其他的进程都是bash的子进程。 通过getcwd获取实时的cwd通过putenv导入环境变量
//获取当前路径信息
string GetPWD()
{if(nullptrgetcwd(cwd,sizeof(cwd)))return None;snprintf(pwdenv,sizeof(pwdenv),PWD%s,cwd);//更新envputenv(pwdenv);return cwd;
}myshell维护自己的环境变量
环境变量和本地变量是存在于shell中的一个表。这两张表就是全局的char*数组。指向很多的字符串。后序我们碰见要导入环境变量的命令我们直接在shell中的genv数组指向一个堆空间然后把第一个为空的数组指向这个字符串。
为什么要新申请空间然后拷贝再指向
因为我们每执行一个命令argv都是会变化的。如果我们直接让genv的元素指向argv的元素以后会发生变化。这样环境变量就找不到了。