核心: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
}
运行结果: