一、exec函数说明
fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。
二、exec函数族语法
所谓exec函数族,其实有六种以exec开头的函数,统称exec函数:
头文件:#include <unistd.h>
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[]);
简单来说,exec函数族都是以exec开头,后面跟的不同字母表示不同的涵义:
l 表示 list,指代的是命令行参数列表。
p 表示 path,指定搜索文件file时所使用的path变量。
v 表示vector,指代的是命令行参数数组。
e 表示 environment,指代的是环境变量数组。
函数参数
path 表示要执行的程序路径,可以是绝对路径或是相对路径。
file 表示要执行的程序名称,如果该参数中包含/字符则视为路径名并直接执行,否则则视为单独的文件名,系统将会根据环境变量 PATH中设置的路径顺序去搜索指定的文件。
argv 表示命令行参数的矢量数组
envp 表示带有该参数的exec函数可以在调用时指定一个环境变量数组,其他不带该参数的exec函数则使用调用进程的环境变量。
arg 表示程序的第0个参数,也就是程序名本身,相当于argv[0]。
… 表示命令行参数列表,调用相应程序时有多少个命令行参数就需要有多少个输入参数项。
返回值
函数执行成功不会返回,若执行失败则返回-1,失败原因会记录在error中。
-
个人理解:(1)exec相当于在执行这个程序的过程中去执行了另一个程序,执行完另一个程序并不返回未执行完的程序。
(2)第一个参数相当于去找到要执行文件的位置,后面的参数想到与shell命令中的参数。
例:execl("/bin/ls", “ls”, “-l”, NULL);相当于在shell下执行 ls -l
(3)最后一个参数指针需要指向空字符串,NULL或者0;
作业:
编程将转换成大写字母的26个英文字母进行输出。要求:
1、要转换的字符从键盘读入;
2、生成子进程,子进程的功能是输出大写的26个字母,exec系列函数加载子进程的功能;
3、从键盘读入的字符作为转换函数的参数;
4、输入特定字符可以结束转换过程。
思路:在该函数中获取从键盘输入的字母,进行判断。创建进程,调用execl函数执行test-exec-atoA文件,
并将输入字符通过传参到test-exec-atoA中
//test-exec.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
char buf[1024]; //创建一个数组,用于存放键盘输入字符
pid_t pid; //创建pid_d 类型的变量,用于表示fork的返回值
printf("===输入字符将转换成大写===\n");
while(1)
{
printf("请输入要转换字符,输入0退出:");
scanf("%s",buf); //键盘输入
if(strcmp(buf,"0")==0) //判断,如果输入为0,退出程序
break;
pid = fork(); //创建进程
if(pid < 0) //判断返回值小宇0,创建进程失败
{
perror("fork()");
exit(1); //创建进程失败,使用exit非正常退出
}else if(pid == 0) //判断返回值等于0,执行子进程
{
execl("./test","./test",buf,NULL); //调研execl函数,执行test文件,并将传入参数buf
exit(1); //execl执行失败,使用exit非正常退出
}else
{
wait(); //父进程处于等待状态
}
}
return 0;
}
//test-exec-atoA.c
//作为test-exec.c的执行文件,实现小写字符转大写字母
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
char buf[1024];
int i;
strcpy(buf,argv[1]); //将argv【1】的值赋予buf
for(i=0;buf[i]!='\0';i++) //循环判断每一位字符
{
if(buf[i] >= 'a' && buf[i] <= 'z') //若为小写字母,将-32转换为大写
printf("%c",buf[i] - 32);
else //若为其他,直接输出
printf("%c",buf[i]);
}
printf("\n");
}
执行后如下: