测试代码
//在fork出的两个子进程中分别执行execl和execlp两个函数, exec函数执行的可执行文件均为同目录下的echoall程序
//execle_execlp.c
char *env_init[] = {"USER=unkown","PATH=/home/atticus/apue/8_Process_Control",NULL};
int main(void){
//char **ptr;
//extern char **environ;
pid_t pid;
if((pid=fork())<0){
fprintf(stderr,"1st fork error: %s\n",strerror(errno));
exit(1);
}
//child1
if(pid == 0){
if((execle("/home/atticus/apue/8_Process_Control/echoall","echoall","child1",(char *)0,env_init)) == -1){
fprintf(stderr,"execle error: %s\n",strerror(errno));
exit(1);
}
}
if(waitpid(pid,NULL,0) < 0){
fprintf(stderr,"1st waitpid error: %s\n",strerror(errno));
exit(1);
}
if((pid=fork())<0){
fprintf(stderr,"2nd fork error: %s\n",strerror(errno));
exit(1);
}
//child2
if(pid == 0){
//check all the environment variable in child 2 process
// for(ptr=environ; *ptr != 0; ptr++){
// printf("%s\n",*ptr);
// }
if((execlp("echoall","echoall","child2",(char *)0)) == -1){
fprintf(stderr,"execlp error: %s\n",strerror(errno));
exit(1);
}
}
exit(0);
}
//生成可执行文件echoall的源代码
//echoall.c (存放在当前工作目录下, 当前工作目录并不处于环境变量的PATH中)
int main(int argc, char **argv){
int i;
char **ptr;
extern char **environ;
printf("------the result of calling the exec function is as follows:------\n");
//print all the argument
for(i=0; i<argc; i++){
printf("argv[%d]: %s\n",i,argv[i]);
}
//print all the environment variable
for(ptr=environ; *ptr != 0; ptr++){
printf("%s\n",*ptr);
}
exit(0);
}
代码执行结果的分析
开始时, 确认echoall可执行代码无bug, 编译并执行execle_execlp.c, 结果execle函数完美执行, 但execlp函数一直报错execlp error: No such file or directory
, 由于我对课本中对该函数的阐述产生误解, 所以我认为execlp函数会从环境变量中的PATH中存放的路径和当前工作目录中去找这个目标执行文件, 但事实上execlp只会从环境变量的PATH中存放的路径去寻找, 而不会去当前工作目录中找. 所以通过将当前工作目录加到环境变量中, execlp函数也完美执行
如何添加环境变量
详细参考这篇文章linux查看、添加、删除环境变量, 下面是我总结的一些添加环境变量时的细节
- 添加针对所有用户且永久生效的环境变量: 需要root权限, 具体步骤是更改
/etc/profile
文件, 更改完之后需要执行命令source /etc/profile
后才会生效 - 添加只针对单个用户的环境变量: 更改
~/.bash_profile
文件, 更改完之后同样需要执行命令source ~/.bash_profile
后才会生效 - 添加只针对当前shell临时环境变量: 直接运行在shell中执行命令
export PATH=[to add]:$PATH
, 此临时环境变量只在当前shell有效, 打开新的shell就会失效