【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;
}
相关推荐
瑞克-桑切斯5 小时前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
vibecode6 小时前
网站服务器失去响应怎么解决?我把连接超时和读超时这两段计时拆开跑了一遍
运维·服务器
工业一体机老司机7 小时前
Docker部署工控机采集服务 Compose编排与开机自启
运维·docker·容器
迪康Defender8 小时前
终端供应链安全:应用白名单与软件正版化检测落地|终端安全治理实践
运维·服务器·网络·安全·web安全·自动化·运维开发
lzx_0028 小时前
Linux 进程(二) 深入理解进程
linux
沫璃染墨9 小时前
从零入门计算机网络系列(十二):HTTP长连接与会话管理详解——从Connection到Cookie与Session
linux·服务器·c++·tcp/ip·ubuntu·http·交互
温暖小土9 小时前
在 CentOS 上安装 Redis Stack
linux·redis·centos
GeW10 小时前
国产化替代进入深水区之后Linux 与数据库为什么必须走向重建
linux
万联WANFLOW11 小时前
异地厂区视频监控远程运维:从组网到安全的实施要点
运维·网络·安全·企业组网·sdwan
衍玊11 小时前
深入剖析 TCP/IP 网络通信原理与内核实现
服务器·网络·tcp/ip