【Linux】谨慎使用system函数以及对应解决方案

概述

使用system()函数并不是核心,它的返回值、它所执行命令的返回值以及命令执行失败原因如何定位,这才是重点。


system函数剖析

c 复制代码
int system(const char * cmdstring)
{
    pid_t pid;
    int status;

    if(cmdstring == NULL)
    {
        return (1);  //如果cmdstring为空,返回非零值,一般为1
    }

    if((pid = fork())<0)
    {
        status = -1;  //fork失败,返回-1
    }
    else if(pid == 0)
    {
        execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
        _exit(127); // exec执行失败返回127,注意exec只在失败时才返回现在的进程,成功的话现在的进程就不存在
    }
    else //父进程
    {
        while(waitpid(pid, &status, 0) < 0)
        {
            if(errno != EINTR)
            {
                status = -1; //如果waitpid被信号中断,则返回-1
                break;
            }
        }
    }
    return status; //如果waitpid成功,则返回子进程的返回状态
}

(1)系统中的system()函数确实执行了一系列的操作来执行用户指定的命令。

首先,它通过fork()创建一个子进程。

接着,在这个子进程中,它调用exec()系列函数来执行用户提供的命令字符串。

在父进程中,system()会调用wait()来等待子进程结束并收集其退出状态。

(2)在执行过程中,system()会调用/bin/sh来执行命令,通常/bin/sh是指向实际shell程序的符号链接,比如bash。使用-c选项告诉shell从提供的字符串中读取要执行的命令。
在命令执行期间,SIGCHLD信号被忽略,这样内核就不会发送子进程结束的信号给父进程,直到命令执行完成。同时,SIGINT和SIGQUIT信号也被忽略,意味着即使进程接收到这些信号,也不会立即响应。

(3)system()函数返回不同的值以表示不同的执行结果。

如果fork()失败,它返回-1。

如果exec()成功执行,即命令正常执行完毕,system()将返回命令通过exit()或return返回的值。需要注意的是,命令执行成功并不一定意味着命令执行的结果是预期的,例如删除一个不存在的文件,命令仍然会成功执行。

如果exec()执行失败,如命令不存在或被信号中断,system()将返回127。

如果传递给system()的命令参数为NULL,则通常返回非0值,通常为1。

解决方案

方案一、使用execvp函数

execvp()会从环境变量所指的目录中查找符合参数 file 的文件名, 找到后执行该文件, 然后将第二个参数argv 传给该执行的文件。

返回值:如果执行成功则函数不会返回, 执行失败则直接返回-1。

方案二、使用popen()函数替代

控制能力更强:popen()允许你创建一个管道,从而能够读取或写入子进程的输入或输出。而system()只能执行命令,并等待其完成,无法直接与子进程的I/O进行交互。

使用更加灵活:popen()提供了更多的参数,使得你可以更精确地控制子进程的行为。例如,你可以指定子进程的输入和输出文件描述符,或者指定子进程的环境变量等。

安全性更高:popen()函数不会自动执行shell,因此它不容易受到shell注入攻击。而system()函数则需要执行shell,因此更容易受到此类攻击。

返回值更清晰:popen()函数只返回两个值:成功返回子进程的status,使用WIFEXITED相关宏就可以取得command的返回结果;失败返回-1,我们可以使用perro()函数或strerror()函数得到有用的错误信息。

这里小编,将解决方案接口代码奉上,可以直接调用接口使用。
system 方案

相关推荐
fiveym6 分钟前
CPU睿频与核心核心问题全解析
运维·硬件架构
天码-行空8 分钟前
【大数据环境安装指南】HBase集群环境搭建教程
大数据·linux·运维·hbase
天空之外1369 分钟前
生成一个带 IP 的自签证书、制作Http证书
linux·运维·服务器
广州服务器托管20 分钟前
[2026.1.6]WINPE运维版20260106,带网络功能的PE维护系统
运维·开发语言·windows·计算机网络·个人开发·可信计算技术
希赛网23 分钟前
华为认证HCIP数通备考资源、模拟练习题库哪里下载?
服务器·网络工程师·华为认证·hcip
恒创科技HK27 分钟前
2026年香港服务器走CN2线路具有哪些优势?
运维·服务器
释怀不想释怀35 分钟前
linux常见安装(JDK,mysql,nginx)
linux·运维·服务器
杰克崔38 分钟前
do_exit的hungtask问题及coredump的实验及原理分析一
linux·运维·服务器·车载系统
BigBigHang44 分钟前
【docker】cloudbeaver的docker-compose及一些踩坑
运维·docker·容器
pengdott44 分钟前
Linux进程数据结构与组织方式深度解析
linux·运维·服务器