linux之进程管理--自主shell
2026/7/27 7:29:27 网站建设 项目流程

shell的命令行设计

其中包含用户名,系统,当前所处的文件夹

这些信息我们可以从环境变量里面筛选得到

使用getenv获取,在封装为函数,获取我们想要的信息

变成函数提取出去

void PrintCommmandLine() { printf("[%s@%s %s]#", GetUSER(), GetHOSTNAME(), GetPWD()); fflush(stdout); }

现在我们暂且让路径是这个样子

获取用户输入

,我们接下来再看

ls -l -a

首先我们要将输入的命令,进行解析按照空变成->ls -l -a. strtok函数在这里很有用

要选择什么来进行输入呢??

scanf??->scanf是以空格作为分割符,在这里显然不太合适

这里我推荐使用fgets

char *fgets(char *str, int n, FILE *stream);

剔除换行

但是我们发现这里会多了一些不必要的换行.因为我们每一次输入的结尾一定会按了一下enter也就是换行所以我们这里要将command_line的末尾用\0来代替

if( fgets(command_line,sizeof(command_line),stdin)==NULL) continue; command_line[strlen(command_line)-1]='\0';

在变成函数

命令行解析

strtok 详解

实现子串一变多,根据自己设定的分割符

char *strtok(char *str, const char *delim);
  • str:待分割的字符串
  • delim:分隔符集合
  • 返回值
  1. 分割成功:返回当前分割出来的子串首地址
  2. 分割完毕:返回NULL

那怎么获得全部呢

strtok

  • 第一次调用:第一个参数传入待分割字符串数组
    • 找到第一个分隔符:将分隔符改成\0,返回第一段字符串首地址
    • 找不到分隔符:直接返回整个字符串首地址
  • 后续循环调用:第一个参数必须传NULL
    • 从上次停下的位置继续向后查找分隔符,找到就返回下一段地址
    • 再也找不到任何片段时,返回 NULL

strtok在命令解析的使用

执行任务

我们不让父进程执行,要让子进程来执行,一但让父进程来执行进程就会退出我们的命令行操作

根据我们之前讲命令行是放在数组里面的,这里我们要使用的程序替换函数使用带v的比较好

void ExecuteCommand() { pid_t id=fork(); if(id<0) { //创建子进程失败 perror("fork"); } else if(id==0) { //child extern char** environ; execvpe(margv[0],margv,environ); perror("execvp fail"); exit(0); } else{ //parent int status=0; pid_t rid=waitpid(id,&status,0); if(rid>0) { printf("wait success\n"); } else { perror("waitpid"); } } }

我们通过上面的实践发现可以完成很多的命令操作了

存在问题

但是像是一些内建命令还是没有办法实现

还有之前的遗留问题,

这里应该只有myshell

解决相应的问题

解决cd的问题

首先cd命令应该要由父进程执行,如果让子进程执行,他结束后不会和父进程同步更新


解决工作目录打印的问题

查看env

cd回到家目录

再次查看时

现象说明

  1. 启动 myshell:环境变量PWD=/xxx/Myshell
  2. 执行cdchdir()成功,内核目录切换到家目录
  3. 但是代码没有更新环境变量 PWD,内存里依然保留旧值
  4. 执行外部命令pwd
    • 系统pwd命令优先读取环境变量 PWD,打印旧路径;

此时我们发现环境变量不会自主更新,所以我们要自己来更新pwd,通过cd时来更新

解决部分echo内建命令

定义全局变量,将退出码记录出来,要在父进程执行或者子进程执行时即使更新退出码

对于子进程,我们让父进程waitpid来获得子进程的退出码

父进程自己来来更新退出码

获取环境变量

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询