lv5 嵌入式开发-2 exec函数族

目录

[1 进程 -- exec函数族](#1 进程 – exec函数族)

[1.1 exec函数族特点](#1.1 exec函数族特点)

[1.2 进程 -- execl / execlp使用方法](#1.2 进程 – execl / execlp使用方法)

[1.3 进程 -- execv / execvp](#1.3 进程 – execv / execvp)

[2 进程 -- system](#2 进程 – system)

[3 exec族要点演示](#3 exec族要点演示)


掌握:exec函数族、system

1 进程 -- exec函数族

执行程序,通孔ps -elf发现,父进程是bash。这意味着该进程是由一个 bash shell 中启动的。

1.1 exec函数族特点

  • 进程调用exec函数族执行某个程序
  • 进程当前内容被指定的程序替换(重要特点)
  • 实现让父子进程执行不同的程序(fork父子进程执行的是一个程序,下面是操作方法即原理)

-父进程创建子进程

-子进程调用exec函数族

-父进程不受影响

1.2 进程 -- execl / execlp使用方法

复制代码
#include  <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);   //区别是不需要完整路径
  • 成功时执行指定的程序;失败时返回EOF
  • path 执行的程序名称,包含路径
  • arg... 传递给执行的程序的参数列表
  • file 执行的程序的名称,在PATH中查找(需要环境变量中添加)

示例1:

执行ls命令,显示/etc目录下所有文件的详细信息

复制代码
if(execl("/bin/ls", "ls", "-a", "-l", "/etc", NULL) < 0){
    perror("execl");
}  
  
if(execlp("ls", "ls", "-a", "-l", "/etc", NULL) < 0){   
    perror("execlp");
}  

0号参数即使命令本身,后面再加其他参数

最后参数必须加NULL空指针

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main(){

   printf("before exec\n");
   if(execlp("ls","ls","-a","-l","./",NULL)<0){
	perror("execl");
   }


}

1.3 进程 -- execv / execvp

复制代码
#include  <unistd.h>
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

成功时执行指定的程序;失败时返回EOF

arg... 封装成指针数组的形式

示例:

执行ls命令,显示/etc目录下所有文件的详细信息

复制代码
char  *arg[] = {"ls", "-a", "-l", "/etc", NULL};  
   
if(execv("/bin/ls", arg) < 0)
{      
    perror("execv");   
}       

if(execvp("ls", arg) < 0) 
{      
    perror("execvp");   
}  

#include <stdio.h>
#include <unistd.h>

int main(){
   char *agv[] = {"ls","-a","-l","./",NULL};

   if(execv("/bin/ls",agv)<0){
	perror("execv");
   }


}


linux@linux:~/Desktop$ ./a.out 
total 24
drwxr-xr-x  2 linux linux 4096 Sep 18 10:32 .
drwxr-xr-x 22 linux linux 4096 Sep 18 10:32 ..
-rwxrwxr-x  1 linux linux 7330 Sep 18 10:32 a.out
-rw-rw-r--  1 linux linux  184 Sep 16 11:24 fork.c
-rw-rw-r--  1 linux linux  157 Sep 18 10:32 test.c
linux@linux:~/Desktop$ ls -a -l ./
total 24
drwxr-xr-x  2 linux linux 4096 Sep 18 10:32 .
drwxr-xr-x 22 linux linux 4096 Sep 18 10:32 ..
-rwxrwxr-x  1 linux linux 7330 Sep 18 10:32 a.out
-rw-rw-r--  1 linux linux  184 Sep 16 11:24 fork.c
-rw-rw-r--  1 linux linux  157 Sep 18 10:32 test.c
linux@linux:~/Desktop$ 

2 进程 -- system

复制代码
#include <stdlib.h>
int system(const char *command);

成功时返回命令command的返回值;失败时返回EOF

当前进程等待command执行结束后才继续执行

其原理也是fork的子进程,执行完不会被替代

示例;

复制代码
#include <stdio.h>
#include <stdlib.h>

int main(){
	system("ls -a -l ./");
}

3 exec族要点演示

示例

cpp 复制代码
//a.out
#include <stdio.h>
int main(int argc,char **argv){    
    printf("hello world %s,%s\n",argv[1],argv[2]);
}

#include <stdio.h>
#include <unistd.h>

//test
#include <stdio.h>
#include <unistd.h>

int main(){

	printf("before exec\n");
	if(execlp("./a.out","./a.out","abc","def",NULL)<0){
		perror("execv");
	}
    printf("after exec\n");
		  	
}

printf没有执行,因为a.out把程序全部替换了。

如果想不被替换?

可以写一个子程序,使用exec

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main(){
   pid_t pid;
   printf("before exec\n");
   pid = fork();
   if(pid==0){
   	if(execl("/bin/ls","-a","-l","./",NULL)<0){
		perror("execl");
   	}
   }
   	printf("after execl\n");

}

printf被打印出来了。

相关推荐
Johny_Zhao8 小时前
网络安全等级保护测评实施方案
linux·网络·人工智能·网络安全·信息安全·云计算·等保测评·系统运维·itsm
落羽的落羽9 小时前
【AI】快速理解AI应用的相关名词概念
linux·c++·人工智能·python·计算机网络·算法
刚入门的大一新生9 小时前
Linux-进程控制
linux·运维·服务器·c++
上火的金鱼妹9 小时前
K8S基础组件作用和关系整理
linux·运维·服务器·kubernetes
Vcaker10 小时前
Linux学习25-harbor私有仓库部署
linux·运维·学习
刃神太酷啦10 小时前
Redis 进阶核心:持久化 (RDB/AOF)、事务与主从复制全解析----《Hello Redis!》(5)
linux·c语言·数据库·c++·redis·缓存·bootstrap
编程的一拳超人10 小时前
DeepSeek Harness Linux/macOS/Windows 本地下载、启动与模型配置指南
linux·windows·macos·deepseek
时凌云.10 小时前
【2026最新】JDK 下载安装与环境配置全教程(Windows/Mac/Linux 三平台,零基础友好)
java·linux·macos
不懂的浪漫11 小时前
ToDesk 连接 Linux 后分辨率过低的解决方法
linux·运维·数据库
广州灵眸科技有限公司11 小时前
从手动三步到上电即连:4G模组systemd开机自连方案
linux·运维·服务器·开发语言·网络·人工智能·php