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

概述

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


system函数剖析

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 方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/599829.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第十八天:二叉树的层序遍历(中间放假)

代码随想录算法训练营第十八天&#xff1a;二叉树的层序遍历&#xff08;中间放假&#xff09; ‍ ​​ 102.二叉树的层序遍历 力扣题目链接(opens new window) 给你一个二叉树&#xff0c;请你返回其按 层序遍历 得到的节点值。 &#xff08;即逐层地&#xff0c;从左到右…

速览Coinbase 2024Q1 财报重点:业务全面开花,净利润达11.8亿美元

作者&#xff1a;范佳宝&#xff0c;Odaily 星球日报 近期&#xff0c;Coinbase 发布了其 2024 年第一季度财报。 报告显示&#xff0c;Coinbase 第一季度营收为 16.4 亿美元&#xff0c;高于分析师平均预期的 13.4 亿美元&#xff1b;净利润为 11.8 亿美元&#xff0c;合每股…

关于Centos 7/8 网络设置 与工具连接

网络三步曲的配置 1、首先更改虚拟机的网络配置 查看子网地址以及网关 如果有要求需要更改IP地址&#xff0c;规定第三位是指定数值&#xff0c;那么需要全部更改 例如&#xff0c;IP地址为192.168.200.30 其中200为重点&#xff0c;更改时为以下步骤 1、点击DHCP设置&#x…

贪吃蛇大作战(C语言--实战项目)

朋友们&#xff01;好久不见。经过一段时间的沉淀&#xff0c;我这篇文章来和大家分享贪吃蛇大作战这个游戏是怎么实现的。 &#xff08;一&#xff09;.贪吃蛇背景了解及效果展示 首先相信贪吃蛇游戏绝对称的上是我们00后的童年&#xff0c;不仅是贪吃蛇还有俄罗斯⽅块&…

找不到模块“vue-router”。你的意思是要将 moduleResolution 选项设置为 node,还是要将别名添加到 paths 选项中?

在tsconfig.app.json中添加&#xff0c;记得一定是 tsconfig.app.json 中&#xff0c;如添加到 tsconfig.node.json 还是会报错的 哈哈哈哈&#xff0c;不瞒你们&#xff0c;我就添加错了&#xff0c;哈哈哈。所以这也算写一个demo提醒自己 "compilerOptions": {&qu…

【牛客】排列计算

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 如果直接涂色来计算单点权重&#xff0c;2e5*2e5必然超时。 所以用差分进行优化。 3. 代码实现 #include<bits/stdc.h> using name…

Go语言fmt包深度探索:格式化输入输出的利器

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 &#x1f3ad; 引言一、基础输出函数fmt.Print与fmt.Println&#x1f4cc; fmt.Print&#xff1a;纯粹输出&#xff0c;不带换行&#x1f4cc; fmt.Println&#xff1a;输出后自动添加换行符 二、格式化输出fmt.Printf&…

鸿蒙开发接口Ability框架:【@ohos.application.missionManager (missionManager)】

missionManager missionManager模块提供系统任务管理能力&#xff0c;包括对系统任务执行锁定、解锁、清理、切换到前台等操作。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 impo…

“Postman 中文版使用教程:如何切换到中文界面?”

Postman 的很好用的接口测试软件。但是&#xff0c;Postman 默认是英文版的&#xff0c;也不支持在软件内切换为中文版。很多同学的英语并不是很好&#xff0c;看到一堆的英文很是头痛。 今天我们来介绍下&#xff1a;切换到 Postman 中文版的方法。想要学习更多的关于 Postma…

Type-C转音频(USB2.0数据传输)+PD充电芯片乐得瑞LDR6500/LDR6023

LDR6500 USB-C DRP 接口 USB PD 通信芯片概述 Type-C转音频(USB2.0数据传输)PD充电芯片乐得瑞LDR6500LDR6500是乐得瑞科技针对USB Type-C标准中的Bridge设备而开发的USB-C DRP&#xff08;Dual Role Port&#xff0c;双角色端口&#xff09;接口USB PD&#xff08;Power Deliv…

Qt---day2-信号与槽

1、思维导图 2、 拖拽式 源文件 #include "mywidget.h" #include "ui_mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::MyWidget) { ui->setupUi(this); //按钮2 this->btn2new QPushButton("按钮2",th…

LeetCode 面试经典150题 252.会议室

题目&#xff1a;给定一个会议时间安排的数组 intervals &#xff0c;每个会议时间都会包括开始和结束的时间 intervals[i] [starti, endi] &#xff0c;请你判断一个人是否能够参加这里面的全部会议。 思路&#xff1a;因为一个人在同一时刻只能参加一个会议&#xff0c;因此…

选择适用的无尘棉签:保障洁净生产环境下的高效擦拭

随着洁净生产条件的日益普及和无尘级别要求的提高&#xff0c;无尘擦拭用品成为广大用户追捧的必备工具。在这个领域&#xff0c;无尘棉签作为一种高效的擦拭工具&#xff0c;扮演着重要的角色。然而&#xff0c;面对市场上种类繁多的无尘棉签&#xff0c;如何选择最合适的产品…

linux 调试-kdb 调试内核-1

目标&#xff1a;打印bcm2835_spi_transfer_one 是如何从用户空间开始调用的 1. kernel 配置 KDB配置选项 添加 spi 控制器驱动 和 spi 设备驱动 2. 调试流程 调试内核-系统启动之后 1. 开发板进入kdb,等待pc 连接 rootraspberrypi:~# echo "ttyS0,115200"…

Python做自动化测试必知必会思维导图

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

DetectoRS:门控融合

论文标题&#xff1a;DetectoRS: Detecting Objects with Recursive Feature Pyramid and Switchable Atrous Convolution 论文地址&#xff1a;https://arxiv.org/pdf/2006.02334 代码地址&#xff1a;https://github.com/joe-siyuan-qiao/DetectoRS/blob/612916ba89ad6452b07…

高项第四版 十大管理及49个过程【背】作业分享

项目管理 1.十大管理【背】 包括&#xff08;口诀:范进整狗子&#xff08;沟质&#xff09; 才&#xff08;采&#xff09;干成疯子&#xff08;风资&#xff09;&#xff09;: &#xff08;1&#xff09;项目整合管理:识别、定义、组合、统一和协调各项目管理过程组的各个过…

OpenCV 入门(三)—— 车牌筛选

OpenCV 入门系列&#xff1a; OpenCV 入门&#xff08;一&#xff09;—— OpenCV 基础 OpenCV 入门&#xff08;二&#xff09;—— 车牌定位 OpenCV 入门&#xff08;三&#xff09;—— 车牌筛选 OpenCV 入门&#xff08;四&#xff09;—— 车牌号识别 OpenCV 入门&#xf…

【SSM进阶学习系列丨分页篇】PageHelper 分页插件集成实践

文章目录 一、说明什么是分页PageHelper介绍 二、导入依赖三、集成Spring框架中四、编写Service五、编写Controller六、编写queryAllByPage页面展示数据 一、说明 什么是分页 ​ 针对分页&#xff0c;使用的是PageHelper分页插件&#xff0c;版本使用的是5.1.8 。 ​ 参考文档…

【typescript 小秘籍 - 类型自动推导】

今天发现个typescript的小技巧&#xff0c;原来在vscode里面 typescript是可以根据数据&#xff0c;自动推导其类型的&#xff0c;这样就不用自己去手敲定义了。比如 鼠标移动到person上&#xff0c;可以看到 其自动推导了person的类型 然后直接复制下来 直接使用即可。
最新文章