【Linux系统编程】system函数和exec函数族的使用

system函数和exec函数族的使用

1.作用:

实现在一个进程中调用执行另外一个进程

2.system的用法

c 复制代码
int system(const char *command)  
    参数: command --》你要执行的shell命令或者可执行程序  
       用法一:执行shell命令
       用法二:执行另外一个可执行程序
               比如:开发板上有一个madplay的程序,用来播放音频文件的
                     开发板本身没带扬声器(需要插耳机到开发板绿色的音频输出口)
                     播放音乐:  madplay  音乐的路径名 
                                 madplay  /1.mp3
                     代码实现:  
							system("madplay /1.mp3 &");       //madplay后台播放歌曲
							system("madplay /1.mp3");         //madplay前台播放歌曲
							前台播放无法实现暂停,继续,退出	-控制台被占用
                 暂停音乐:  system("killall -STOP madplay");  //给madplay发送暂停信号
                 继续播放:  system("killall -CONT madplay");  //给madplay发送继续信号
                 退出播放:  system("killall -KILL madplay");  //给madplay发送杀死信号

小结:linux中给进程发送信号有两个命令可以使用

命令1: kill 信号的名字/信号的序号 进程的id号 比如: kill -9 5468

//给5468这个进程发送9号信号

kill -SIGKILL 5468 //给5468这个进程发送SIGKILL号信号

kill -KILL 5468 //给5468这个进程发送SIGKILL号信号

命令2: killall 信号的名字/信号的序号 进程的名字 比如: killall -9 hello

//给hello这个进程发送9号信号

killall -SIGKILL hello //给hello这个进程发送SIGKILL号信号

killall -KILL hello //给hello这个进程发送SIGKILL号信号

示例代码1:system执行shell命令

c 复制代码
#include <stdlib.h>
#include <unistd.h>
/*
    system执行shell命令
*/

int main(int argc, char const *argv[])
{
    system("ls -l");
    sleep(3);
    system("pwd");
    return 0;
}

示例代码2:system执行另外一个程序

c 复制代码
// hello.c
#include <stdio.h>

int main()
{
    while(1) 
    {
        printf("hello world\n");  
        sleep(2);
    }
    return 0;
}

// system执行另外hello.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
/*
    system执行另外一个进程(编译好的程序)
    实现在一个进程中调用执行另外一个进程
*/

int main()
{
    /*
        system调用执行另外一个独立的进程分为两种情况
           情况1:hello里面有死循环,会影响你当前进程后面的代码执行
                  解决方法1:让hello在后台执行,后台执行不会影响到后续的代码
                  解决方法2:借助今天学习fork函数,搞个子进程出来,通过子进程执行system
    */
    //方法1:让hello在后台执行,后台执行不会影响到后续的代码
    //system("./hello &");  //&符号的意思是后台执行hello
    
    // for(;;)
    // {
        // printf("main main main,我的ID: %d\n",getpid());
        // sleep(1);
    // }
    
    
    //方法2:借助fork函数,创建个子进程出来,通过子进程执行system
    pid_t id;
    id=fork();
    if(id>0) //父进程
    {
        for(;;)
        {
            printf("main main main,我的ID: %d\n",getpid());
            sleep(1);
        }
    }
    else if(id==0) //子进程
    {
        system("./hello");
    }
}

3.exec函数族的用法

特点:

  • exec函数族里面的6个函数会替换你当前进程后面的代码,导致你当前进程后面的代码无法执行
  • system函数不会影响当前进程执行后面的代码
c 复制代码
int execl(char *path,char *arg,...);
    参数:path --》你要执行的shell命令/程序的路径名
          arg --》你的shell命令/程序的参数
int execlp(char *file,char *arg,...);
    参数:file --》你只需要写shell命令/程序的名字即可
int execle(const char *path, const char *arg,
          ..., char *envp[]);
    参数:path --》你要执行的shell命令/程序的路径名
          arg --》你的shell命令/程序的参数
          envp[] --》存放需要设置环境变量
int execv(const char *path, char *const argv[]);
    参数:argv[] --》存放命令参数
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
          char *const envp[]);
          
  l --》参数以列表的形式逐一列举
  p --》表示从系统的环境变量中去查找要执行的shell命令或者程序
  e --》表示在执行命令的时候,可以顺便设置环境变量
        允许改变子进程的环境变量,无后缀e时,子进程使用当前程序的环境 
  v --》参数需要使用指针数组存放

示例代码1:execl执行shell命令

c 复制代码
#include <unistd.h>

/*
    execl执行shell命令
    实现在一个进程中调用执行另外一个进程
    exec函数族:
        l --》参数以列表的形式逐一列举
*/

int main(int argc, char const *argv[])
{
    execl("/usr/bin/ls", "ls", "-l", NULL);
    return 0;
}

示例代码2:execl执行另外一个程序

c 复制代码
#include <unistd.h>

/*
    execl执行另外一个程序
    exec函数族:
        l --》参数以列表的形式逐一列举
*/

int main(int argc, char const *argv[])
{
    /* 既可用绝对路径,也用相对路径 */
    execl("hello", "./hello", NULL);
    return 0;
}

示例代码3:execlp的使用

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

/*
    execlp的使用
    实现在一个进程中调用执行另外一个进程
    exec函数族:
        l --》参数以列表的形式逐一列举
        p --》表示从系统的环境变量中去查找要执行的shell命令或者程序
*/

int main(int argc, char const *argv[])
{
    execlp("ls", "ls", "-l", "-a", NULL);
    return 0;
}

示例代码4:execle的使用

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

/*
    execle的使用
    实现在一个进程中调用执行另外一个进程
    exec函数族:
        l --》参数以列表的形式逐一列举
        p --》表示从系统的环境变量中去查找要执行的shell命令或者程序
        e --》执行程序的时候,可以顺便设置那个程序的环境变量
*/

int main(int argc, char const *argv[])
{
    // 定义自定义环境变量数组,必须以 NULL 结尾
    char *const envp[] = {
        "MY_VAR=HelloFromExecle",
        "ANOTHER_VAR=12345",
        NULL // 重要:环境变量数组必须以 NULL 结尾
    };

    printf("Before execle...\n");

    // 调用 execle
    // path: "/usr/bin/env" (要执行的程序路径)
    // arg0: "env" (程序名,对应 argv[0])
    // arg1: NULL (没有其他命令行参数,列表以 NULL 结尾)
    // envp: 自定义的环境变量表
    execle("/usr/bin/env", "env", NULL, envp);

    // 如果 execle 成功,下面的代码不会执行
    // 如果执行到这里,说明 execle 出错了
    perror("execle failed");
    return 1;
}

示例代码5:execv的使用

c 复制代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h> // for exit

int main(int argc, char const *argv[])
{
    printf("Before execv...\n");

    // 定义参数数组,必须以 NULL 结尾
    // 对应命令: /bin/ls -l -a
    char *const args[] = {
        "/bin/ls",  // argv[0]: 程序名(通常也是路径)
        "-l",       // argv[1]: 第一个参数
        "-a",       // argv[2]: 第二个参数
        NULL        // 重要:参数数组必须以 NULL 结尾
    };

    // 调用 execv
    // path: "/bin/ls"
    // argv: args 数组
    execv("/bin/ls", args);

    // 如果 execv 成功,下面的代码不会执行
    // 如果执行到这里,说明出错了
    perror("execv failed");
    return 1;
}

示例代码6:exec和system的区别

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

/*
    exec和system的区别
    
*/

int main()
{
#if 1
    //exec 
    printf("1. 这行会打印\n");
    
    // execlp: 自动从 PATH 查找 ls
    // 注意:如果成功,下面的 printf 永远不会执行!
    execlp("ls", "ls", "-l", "/tmp", NULL);
    
    // 只有当 execlp 出错时,才会执行到这里
    perror("execlp failed");
    printf("2. 这行通常不会打印(除非出错)\n");
#else
    printf("1. 这行会打印\n");
    
    // system 会阻塞,直到 ls 命令执行完毕
    int ret = system("ls -l /tmp");
    
    printf("2. 这行一定会打印,system 返回值为: %d\n", ret);
#endif
    return 0;
}
相关推荐
大树883 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠3 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质3 小时前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush44 小时前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5204 小时前
Linux 11 动态监控指令top
linux
小宇宙Zz4 小时前
Maven依赖冲突
java·服务器·maven
Inhand陈工5 小时前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智5 小时前
ARP代理--工作原理
运维·网络·arp·arp代理
不会C语言的男孩5 小时前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
shushangyun_5 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化