核心:fork+exec
path:新替换的程序的路径名称
int main(int argc, char* argv[],char* envp[])//int main(参数个数 参数内容 环境变量)
arg :传给新程序主函数的第一个参数,一般为程序的名字
arg 后面是剩余参数列表,参数个数可变,必须以空指针作为最后一个参数
exec使用示例:
execl(“/usr/bin/ps”,“ps”,“-f”,(char*)0); //execl(“程序打开”,“替换程序名”,参数...),系统自己写入环境变量,不用手动输入。
execlp(“ps”,“ps”,“-f”,(char*)0) ;//execl(“程序打开路径”,“替换程序名”,参数...),不用给出路径,系统自己查找,系统自己写入环境变量,不用手动输入。
execle(“/usr/bin/ps”,“ps”,“-f”,(char*)0,envp); //execl(“程序打开路径”,“替换程序名”,参数...,环境变量),要手动写入环境变量
char*myargv[10]={"ps","-f"};
execv(“/usr/bin/ps”,myargv); //execl(“程序打开路径”,参数...)
char*myargv[10]={"ps","-f"};
execvp(“ps”,myargv); //execl(“程序打开路径”,参数...)
char*myargv[10]={"ps","-f"};
execve(“/usr/bin/ps”,myargv,envp) //execl(“程序打开路径”,参数...,环境变量),要手动写入环境变量
简陋版mybash命令提示符
代码如下
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<fcntl.h> #include<sys./wait>//调用wait的头文件 int main(int argc, char* argv[], char* envp[]) { if (buff == NULL || myargv == NULL) { return NULL; } int i = 0; char* s = strtok(buff, " ");//buff=cp a.c b.c while (s != NULL) { myargv[i++] = s; s = strtok(NULL, " "); } return myargv[0]; } while (1) { printf("stu@localhost ~$");//打印命令提示符,主机名calhost,在当前家目录里~$ fflush(stuout);//刷新打印出去,因为有缓冲区 char buff[128] = { 0 }; fget(buff, 128, stdin);//键盘获取数据,scanf也可以,从键盘读取128个)fgets会把我们后面敲到的"\n”也读到,但是"ls\n”找不到 buff(strlen(buff) - 1] = 0;//ls,ps-f ,手动设置'\0' if (strcmp(buff, "exit") == 0)//内置命令的实现,比如输入exit退出当前程序 { break; } pid_t pid = fork();//产生子进程 if (pid == -1)//复制子进程失败 { continue; } if (pid == 0) { execlp(buff, buff, (char*)0);//替换(程序名,程序名,参数) exit(0); } wait(NULL);//父进程等待子进程结束,调用wait }
运行结果:
打印错误信息exit退出
小tips:加上错误信息提示:
代码段
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<fcntl.h> #include<sys./wait>//调用wait的头文件 int main(int argc, char* argv[], char* envp[]) { if (buff == NULL || myargv == NULL) { return NULL; } int i = 0; char* s = strtok(buff, " ");//buff=cp a.c b.c while (s != NULL) { myargv[i++] = s; s = strtok(NULL, " "); } return myargv[0]; } while (1) { printf("stu@localhost ~$");//打印命令提示符,主机名calhost,在当前家目录里~$ fflush(stuout);//刷新打印出去,因为有缓冲区 char buff[128] = { 0 }; fget(buff, 128, stdin);//键盘获取数据,scanf也可以,从键盘读取128个)fgets会把我们后面敲到的"\n”也读到,但是"ls\n”找不到 buff(strlen(buff) - 1] = 0;//ls,ps-f ,手动设置'\0' if (strcmp(buff, "exit") == 0)//内置命令的实现,比如输入exit退出当前程序 { break; } pid_t pid = fork();//产生子进程 if (pid == -1)//复制子进程失败 { continue; } if (pid == 0) { execlp(buff, buff, (char*)0);//替换(程序名,程序名,参数) printf("execlp err\n");//此处,打印错误信息提示 exit(0); } wait(NULL);//父进程等待子进程结束,调用wait }
运行结果:
执行空的命令执行不了:
代码段
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<fcntl.h> #include<sys./wait>//调用wait的头文件 int main(int argc, char* argv[], char* envp[]) { if (buff == NULL || myargv == NULL) { return NULL; } int i = 0; char* s = strtok(buff, " ");//buff=cp a.c b.c while (s != NULL) { myargv[i++] = s; s = strtok(NULL, " "); } return myargv[0]; } while (1) { printf("stu@localhost ~$");//打印命令提示符,主机名calhost,在当前家目录里~$ fflush(stuout);//刷新打印出去,因为有缓冲区 char buff[128] = { 0 }; fget(buff, 128, stdin);//键盘获取数据,scanf也可以,从键盘读取128个)fgets会把我们后面敲到的"\n”也读到,但是"ls\n”找不到 buff(strlen(buff) - 1] = 0;//ls,ps-f ,手动设置'\0' if (strcmp(buff, "exit") == 0)//内置命令的实现,比如输入exit退出当前程序 { break; } if (buff[0] == '\0')//空命令判断,命令无效则退出 { continue; } pid_t pid = fork();//产生子进程 if (pid == -1)//复制子进程失败 { continue; } if (pid == 0) { execlp(buff, buff, (char*)0);//替换(程序名,程序名,参数) printf("execlp err\n"); exit(0); } wait(NULL);//父进程等待子进程结束,调用wait }
运行结果: