exec 系列替换过程:
int execl(const char* path, const char * arg,…);
int execlp(const char* file, const char * arg,…);
int execle(const char* path, const char * arg,…,char* const envp[]);
int execv(const char * path, char* const argv[]);
int execvp(const char * file, char* const argv[]);
int execve(const char * path, char* const argv[],char* const envp[]); //系统调用
path:新替换的程序的路径名称
arg :传给新程序主函数的第一个参数,一般为程序的名字
arg 后面是剩余参数列表,参数个数可变,必须以空指针作为最后一个参数
fork 和 exec 联合使用创建一个全新的进程 bash
#include<stdio.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<pwd.h>
#define argc 10
char* get_cmd(char* buff,char* argv[])
{
if(buff==NULL||argv==NULL)
{
return NULL;
}//如果参数为0返回空
char* s=strtok(buff," ");//获取第一个命令
int i=0;
while(s!=NULL)
{
argv[i]=s;//将命令打入数组
i++;
s=strtok(NULL," ");//继续获取剩余参数
}
return argv[0];//返回第一个命令
}
void print_info()
{
char *s ="$";
int uid=getuid();
if(uid==0)
{
s="#";
}
struct passwd *p=getpwuid(uid);
if(p==NULL)
{
printf("$");
fflush(stdout);
return;
}
char hostname[128]={0};
gethostname(hostname,128);
char curr_dir[256]={0};
getcwd(curr_dir,256);
printf("\033[1;34m%s@%s\033[0m \033[1;35m%s\033[0m%s",p->pw_name,hostname,curr_dir,s);
fflush(stdout);
}
int main()
{
while(1)
{
print_info();
char buff[128]={0};
fgets(buff,128,stdin);
buff[strlen(buff)-1]='\0';
char * argv[argc]={0};
char* cmd=get_cmd(buff,argv);//cmd是第一个参数,好区别命令和参数
if(cmd==NULL)
{
continue;
}
else if(strcmp(cmd,"exit")==0)
{
break;
}
else
{
pid_t pid=fork();
if(pid==-1)
{
continue;
}
if(pid==0)
{
execvp(cmd,argv);//cmd是命令,argv是后面的参数
printf("error\n");
exit(0);
}
}
wait(0);
}
exit(0);
}