exec函数族 等
一、exec 函数族
1.1 函数原型

在 Linux 中,并不存在 exec() 函数,exec 指的是一组/簇函数,一共有 6 个:
#include <unistd.h>
int execl (const char *path, const char *arg0, ...);
int execlp (const char *file, const char *arg0, ...);
int execle (const char *path, const char *arg0, ..., 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[]);
注1:exec 族函数执行成功后,此函数后面的代码就执行不到了!! 但只会影响当前进场,而不会影响系统。
注2:其中只有execve()是真正意义上的系统调用,其它都是在此基础上经过包装的库函数。
注3:函数名称中的子母涵义:
l (list):参数地址列表,必须以空指针结尾 ---- NULL是设立的哨兵,必须手动加。
v (vector):存有各参数地址的指针数组的地址。
p (path):按 PATH 环境变量指定的目录搜索可执行文件 ---- 带此字母的函数可以直接使用“文件名”,其他的则必须使用“路径名”。
e (environment):存有环境变量字符串地址的指针数组的地址 ---- 无后缀e时,子进程使用当前程序的环境。
1.2 返回值
一旦调用成功即执行新的程序,即:成功无返回;失败会设置errno并返回:-1,然后从原程序的调用点接着往下执行。
故而,可以直接在 exec 族函数后, 直接调用 perror() 或者 exit(),不需要 if 判断。
最常见的错误:
errno = ENOENT,找不到文件或路径;
errno = EFAULT,数组 argv 和 envp 忘记用NULL结束;
errno = EACCES,没有对要执行文件的运行权限。
1.3 使用参数示例
(1)execl
execl("./a.out", "./a.out", NULL);
execl("/bin/ls", "ls", "-l", NULL);
注1:第一个参数是文件路径,第二个参数是argv[0],之后是传给argv[0]的参数,没有了就哨兵NULL。
注2:execl 执行的是自己的文件;若要用 execl 执行系统的文件,必须写成绝对路径。
(2)execlp
//错误写法: execlp ("ls","-l","-h",NULL);
execlp ("ls","ls","-l","-d","-h",NULL);
注1:第一个参数 file 必须是文件名;最后一个参数必须用空指针(NULL)作结束。
首先,从PATH 环境变量所指的目录中查找符合参数 file 的文件名,找到后便执行该文件;然后,将第二个以后的参数当做该文件的argv[0], argv[1], …。
注2:execlp 执行的是系统的文件
(3)execvp
char * argv[] = {"ls", "-l", "-h", NULL};
execvp("ls", argv);
二、system 函数
2.1 函数原型
#include <stdlib.h>
int system(const char * command);
三、popen 函数
3.1 函数原型
#include <stdio.h>
FILE *popen(const char * command, ocnst char * type);
参数:
comand 为执行命令,
type 为操作类型,只能是读和写的 一种,一般为 “r” 和 “w”, 返回值是一个文件类型指针
示例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
char data[1024] = {0};
FILE *fp;
fp = popen("ps", "r");
int n_read = fread(data, 1, 1024, fp);
printf("read %d bytes, data=%s\n",n_read, data);
return 0;
}
四、 查看时间示例
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("before execl:\n");
// 方法1:使用 exec 函数族
if ( execl ("/bin/date", "date", NULL) == -1) {
printf("execl failed!\n");
perror("why");
}
// 方法2: 使用 system 函数
if ( system("date") == -1 ){
printf("execl failed!\n");
}
printf("after execl\n");
return 0;
}
参考列表:
[1] Linux系统编程——进程替换:exec 函数族
[2] Linux——exec函数族原理及特性、execlp和execl函数
posted on 2023-11-20 17:35 hellcworld 阅读(2) 评论(0) 收藏 举报
浙公网安备 33010602011771号