资讯详情

Linux 进程控制实践:exec 替换、mybash 与 ls 命令实现

📅 2026/11/6 1:42:14 | 华诺云谱 👁 阅读
Linux 进程控制实践:exec 替换、mybash 与 ls 命令实现
exec替换进程Linux中每产生一个全新的进程都是通过forkexec实现0进程除外execl()、execlp()、execle()、execv()、execvp()、execve()前五个是库函数都是借助最后一个实现的最后一个是系统调用替换成功exec系列方法没有返回值没有当前进程跳到新进程后续代码不实现替换失败才会继续执行后续代码int main(int argc,char*argv[],char*envp()) { printf(main pid%d\n,getpid()); execl(/usr/bin/ps,ps,-f,(char*)0); execlp(ps,ps,-f,(char*)0); execle(/usr/bin/ps,ps,-f,(char*)0,envp); char *myargv[]{ps,-f,0}; execv(/usr/bin/ps,myargv); execvp(ps,myargv); execve(/usr/bin/ps,myargv,envp);//系统调用 printf(exec err\n); exit(0); }代码理解用ps命令替换当前进程ps-f显示更多信息遇见(char*)0则传参结束第一个参数ps命令第二个参数ps当前进程的名字可以随机第三种envp将main的环境变量也传给替换的进程在环境变量PATH里面找命令mybash普通命令ls、cp、ps 实现方式bash复制替换内置命令cd、exit 实现方式直接在进程中内置命令即对进程本身进行操作子进程中如果替换为内置命令无法对父进程进行相关操作堆父进程没有影响普通命令如ls父进程中查看有哪些文件子进程中当然也可以查看有哪些文件所以普通命令是可以实现的#includestdio.h #includestdlib.h #includeunistd.h #includestring.h #includesys/wait.h //mybash模仿系统的bashforkexec复制替换 char* Get_cmd(char* buff, char* myargv[])//转换buff[]myargv[0]cp myargv[1]a.c.. { if (buff NULL || myargv NULL) return NULL; char* s strtok(buff, ); int i 0; while (s ! NULL) { myargv[i] s; s strtok(NULL, ); } return myargv[0]; } //打印提示符函数 void printf_info() { char* user_str$; int uidgetuid();//获取当前用户的id号 if(uid0)//管理员 { user_str#; } struct passwd*pgetpwuid(uid);//根据uid得到包含用户名pw_name(std/root)的结构体 if(pNULL)//uid可能是错的导致得不到用户名 { printf(mybash $); fflush(stdout); return; } char host[128]{0}; gethostname(host,128);//gethostname获取主机信息 char cur_dir[128]{0}; getcwd(cur_dir,128);//获取路径 printf(%s%s:%s%s,p-pw_name,host,cur_sir,usr_str); fflush(stdout); } int main() { while (1) { char buff[128] { 0 };//存放命令的数组放到循环里 printf_info(); fgets(buff, 128, stdin);//从键盘读取数据可以读到回车键 buff[strlen(buff) - 1] \0;//把读到的\n转为\0 char* myargv[10] { 0 };//每一个元素都是一个字符串 char* cmd Get_cmd(buff, myargv); if (cmd NULL) continue;//从上重新执行 if (strcmp(cmd, exit) 0)//内置命令exit break; //chdir改变当前路径 if(strcmp(cmd,cd)0)//内置命令cd { if(myargc[1]!NULL) { if(chdir(myargv[1]-1)//成功返回0失败返回-1 { printf(cd err:%s not found\n,myargv[1]); } } coutinue;//没有加路径啥也不干 } //复制 pid_t pid fork(); if (pid -1) continue; //替换 if (pid 0) { execvp(cmd, myargv);//execlp(buff, buff,(char*)0); printf(exec err\n); exit(1); } //子进程代码有exit不管替换成不成功子进程都不可能运行到这里只有父进程才会运行以下代码 wait(NULL);//模拟前台等子进程替换之后的命令运行结束才打出提示符并且处理了僵死进程子进程结束之前父进程处于阻塞状态 } }ls命令​ //Linux程序设计中文第四版 3.8章节 //设计ls 加颜色ls -color #includestdio.h #includestdlib.h #includeunistd.h #includestring.h #inlcudedirent.h int main() { char buff[256]{0}; getcwd(buff,256);//获取当前位置 DIR*pdiropendir(buff);//opensir给一个文件夹的名字返回一个目录流 if(pdirNULL) { printf(无法打开目录流\n); exit(1); } struct dirent*sNULL;//该结构体中有文件名 //while循环那里每次读一个文件 while((sreaddir(pdir))!NULL)//readdir传一个目录流会返回一个结构体指针 { if(strcmp(s-d_name,.)0)//..和.不显示 { continue; } struct strt st; stat(s-d_name,st); if(S_ISDIR(st.st_name))//文件类型是目录 { printf(\033[1;34m%s\033[0m ,s-d_name)//printf设计颜色 } else { printf(%s,s-d_name); } } printf(\n); closesir(pdir);//关闭目录流 } ​
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑