【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;
}
相关推荐
来鸟 鸣间2 小时前
mutex_lock 流程
linux·c语言
秋风&萧瑟2 小时前
【Linux系统编程】Linux多进程介绍及使用
linux·运维·网络
三万棵雪松2 小时前
【Linux 物联网网关主控系统-Web部分(四)】
linux·前端·物联网·嵌入式linux
宵时待雨2 小时前
linux笔记归纳1:linux初识
linux·运维·笔记
Deitymoon2 小时前
linux——线程设置分离属性
linux
|_⊙2 小时前
Linux进程(上)
linux·运维·服务器
feng_you_ying_li2 小时前
linux之git/gdb的使用与介绍
linux
FreeBuf_2 小时前
Nginx-UI 备份恢复漏洞 PoC 公开:攻击者可篡改加密备份并注入恶意配置
运维·nginx·ui
吕司2 小时前
Linux页表的概念
linux·运维·服务器