QT调用linux外部命令或者shell script

目录

原文链接:https://blog.csdn.net/YMGogre/article/details/128973098

0、本文使用的环境配置:

1、新建一个简单的Shell脚本:

2、在Qt中启动外部Shell脚本:

2.1、使用标准库中提供的方法 —— system()

2.2、使用Qt提供的API —— QProcess类

2.2.1、使用start()方法启动外部Shell脚本

3、实例demo:

3.1、demo中的其他内容 —— QSettings

1、新建一个简单的Shell脚本:
        Linux 的 Shell 种类众多,本文使用的是 Bourne Again Shell(/bin/bash),也就是被广泛使用的 Bash。这里我们先新建一个简单的 Bash 脚本给 Qt 程序启动用:

首先前往一个你心仪的用于存放 Shell 脚本的文件夹(我选择在根目录下新建了一个名为“Bash_Script”的文件夹专门用于存放 Bash 脚本),在文件夹内打开终端,如下图所示:
在终端内使用 touch 命令新建一个 *.sh 文件,随后使用 vi / vim / gedit 命令来编辑文件:
touch hello_world.sh
 
sudo gedit hello_world.sh
在打开的文本编辑器中键入以下内容:
# 指定脚本解释器的目录
#!/bin/bash
 
while(true)
do
    echo "Hello World!"
    sleep 1s
done
这是一个一秒打印一次 "Hello World!" 的 Shell 脚本。保存后关闭文本编辑器,回到终端,使用 chmod 命令来为脚本添加可执行权限:
chmod +x ./hello_world.sh
然后键入以下命令就可以执行脚本了:
./hello_world.sh

2、在Qt中启动外部Shell脚本:
2.1、使用标准库中提供的方法 —— system()
system() 的原型为:

#include <stdlib.h>
int system(const char *__command)
        该方法调用 /bin/sh 来执行参数指定的命令,我们知道 /bin/sh 是用于指定脚本解释器的。GNU/Linux 操作系统中的 /bin/sh 本是 Bash (Bourne-Again Shell) 的符号链接,但鉴于 Bash 过于复杂,有人把 Bash 从 NetBSD 移植到 Linux 并更名为 Dash (Debian Almquist Shell),并建议将 /bin/sh 指向它,以获得更快的脚本执行速度。Dash Shell 比 Bash Shell 小的多,符合POSIX标准。

        而 Ubuntu 继承了 Debian,所以从 Ubuntu 6.10 开始 /bin/sh 默认指向 Dash Shell:

        使用该方法十分简单,将想要执行的命令通过参数传递即可,比如我们可以使用绝对路径执行上一章新建的那个 Shell 脚本:

system("/home/xjy/Bash_Script/hello_world.sh");
通过该方法执行的外部脚本输出会在 Qt Creator 中通过应用程序输出栏打印出来:

 

 如果我们希望还是在终端中打印输出,那么我们可以用命令打开一个终端,再把执行脚本的命令传递给新打开的终端,就像下面这样:

system("gnome-terminal -- bash -c '/home/xjy/Bash_Script/hello_world.sh'&");
        这跟我们随意打开一个终端输入命令是一样的效果:

  不同的是现在我们可以在 Qt 中完成这一操作了。

        由以上两种操作可以看出,使用标准库的 system() 方法执行外部 Shell 脚本非常的简单,但我并没有研究如何在使用 system() 方法的情况下将 Shell 脚本的输出打印到我们的应用程序上。而且该方法还有个显而易见的缺点即当我们的 Shell 脚本是需要持续运行时,使用 system() 方法第一种操作(不开新的终端打印输出)去执行它会造成我们的主进程堵塞;而如果使用第二种操作(在终端里打印输出)虽然不会堵塞主进程了,但又会导致每次执行 Shell 都会打开一个终端,不够简练。

        如果你的程序对 Shell 脚本的输出打印位置没有要求或者 Shell 脚本可以迅速执行完毕的话,那就可以简单使用 system() 方法执行外部脚本即可。

2.2、使用Qt提供的API —— QProcess类
        当然,Qt 也提供给我们一个强大的 API 用于执行外部 Shell 脚本或者应用程序。QProcess 类是用于启动外部程序并与之传递信息的类。在 Qt Creator 帮助文档或者官网的帮助文档都提供了该类十分详尽的介绍与使用方法,所以这里笔者就简单介绍了:

在 VxWorks、iOS、tvOS、watchOS 以及通用Windows平台 (Universal Windows Platform) 上不支持 QProcess 类;
一个 QProcess 类的对象用于启动一个外部进程,如果我们想要同时执行多个持续运行的外部 Shell 脚本或应用程序,声明多个 QProcess 对象即可;
QProcess 提供了三个成员方法启动外部进程:
//静态成员方法execute,该方法会在一个新的进程中以arguments参数启动program程序,并等待其执行结束
int execute(const QString &program, const QStringList &arguments)
 
//public成员方法start,该方法会在一个新的进程中启动program程序,命令行参数则在arguments中传递
void QProcess::start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite)
 
//静态成员方法startDetached,该方法以分离进程的方式在一个新的进程中以arguments参数启动program程序
bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(), qint64 *pid = nullptr)
        execute() 方法以堵塞进程的方式启动外部程序,这就和上一节的 system() 方法并无太大区别,这里就不再探讨了。既然选择使用 QProcess 类,那就重点关注 start() 和 startDetached() 方法:

start() 方法以父子进程的方式启动外部程序,父死子亡;
startDetached() 方法以分离进程的方式启动外部程序,调用进程退出,分离进程不受影响继续运行;
        接下来笔者仅探讨使用 start() 方法启动外部 Shell 脚本,对 startDetached() 方法感兴趣的同学可以参考 Qt 官方文档。

2.2.1、使用start()方法启动外部Shell脚本
首先我们需要理解的是,Shell脚本是不需要编译的,而是直接运行解释器,将脚本作为解释器程序参数运行的。所以 start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode = ReadWrite) 方法第一个参数 “程序” 应为脚本解释器程序,而脚本文件(.sh)应当作为运行参数传入(也就是该方法的第二个参数)。所以,正确的调用姿势应当如下面这样:
#include <QProcess>
 
QProcess* executeProcess = new QProcess();
executeProcess->start("/bin/bash", QStringList() << "/home/xjy/Bash_Script/hello_world.sh");
当然,我们也可以通过 setProgram(const QString &program) 方法设置进程要使用的程序;通过 setArguments(const QStringList &arguments) 方法设置在启动进程时传递给被调用程序的参数;最后通过调用 start(QIODevice::OpenMode mode = ReadWrite) 启动进程。但显然这样写更麻烦些,下面是一个例子:
#include <QProcess>
 
QProcess* executeProcess = new QProcess();
executeProcess->setProgram("/bin/bash");
executeProcess->setArguments(QStringList() << "/home/xjy/Bash_Script/hello_world.sh");
executeProcess->start();
如果我们需要打印 Shell 脚本的输出,可以调用 readAllStandardOutput() 方法,不管当前的读通道是什么,该函数将进程标准输出的所有可用数据作为 QByteArray 返回。
QByteArray QProcess::readAllStandardOutput()
此外,QProcess 类提供了一些信号是我们可以使用的:比如说当我们调用 start() 方法时,QProcess 对象会立即进入 Starting 状态;如果进程成功启动,QProcess 会发送 started() 信号,否则发送 errorOccurred(QProcess::ProcessError error) 信号。
        需要注意的是,进程是异步启动的,这意味着 started() 和 errorOccurred() 信号可能会延迟。调用 waitForStarted() 以确保进程已经启动(或启动失败),并且已经发出了那些信号。

还有一些信号比如 readyReadStandardOutput() 信号,当进程通过其标准输出通道 (stdout) 提供了新数据时,就会发出此信号。不管当前的读通道是什么,它都会被触发; 
 


原文链接:https://blog.csdn.net/YMGogre/article/details/128973098

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

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

相关文章

占据80%中国企业出海市场,亚马逊云科技如何为出海客户提供更多资源和附加值

亚马逊云科技就可以做到&#xff0c;作为占据80%中国企业出海市场的亚马逊云科技&#xff0c;其覆盖全球的业务体系&#xff0c;从亚马逊海外购、亚马逊全球开店、亚马逊智能硬件与服务&#xff0c;Amazon Alexa&#xff0c;Amazon Music都是属于亚马逊云科技“梦之队”的一员。…

SDK接口远程调试【内网穿透】

文章目录 1.测试环境2.本地配置3. 内网穿透3.1 下载安装cpolar内网穿透3.2 创建隧道 4. 测试公网访问5. 配置固定二级子域名5.1 保留一个二级子域名5.2 配置二级子域名 6. 使用固定二级子域名进行访问 转发自cpolar内网穿透的文章&#xff1a;Java支付宝沙箱环境支付&#xff0…

使用单片机遇到的几个问题及解决方案1

1.为什么我跟着视频学习的过程中&#xff0c;我没有找到“端口"的选项呢&#xff1f;我甚至没有出现“其他插口”。 想要找到设备管理器最快的方法就是&#xff1a; 首先如果把输入法调为大写形式&#xff0c;然后按下“WINX”&#xff0c;再按“M”就会出现一个设备管理…

Vivado 下 IP核之双端口 RAM 读写

目录 Vivado 下 IP核之双端口 RAM 读写 1、RAM IP 核简介 2、实验任务 3、程序设计 3.1、RAM IP 核配置 3.2、顶层模块设计 &#xff08;1&#xff09;绘制波形图 4、编写代码 4.1、顶层模块 ip_2port_ram 4.2、RAM 写模块设计 4.3、ram_wr 模块代码 4.4、RAM 读模…

Goby 漏洞发布|maxView Storage Manager 系统 dynamiccontent.properties.xhtml 远程代码执行漏洞

漏洞名称&#xff1a;maxView Storage Manager 系统 dynamiccontent.properties.xhtml 远程代码执行漏洞 English Name&#xff1a;maxView Storage Manager dynamiccontent.properties.xhtml RCE CVSS core: 9.8 影响资产数&#xff1a;1465 漏洞描述&#xff1a; maxVie…

架构之冷热分离

本文依据《从程序员到架构师》阅读有感&#xff0c;记录书中案例并且结合作者工作经历进行分析。 当数据量过大&#xff0c;业务查询慢甚至导致数据库服务器CPU飙升&#xff0c;导致数据库宕机&#xff0c;影响用户体验。 场景&#xff1a; 1.客户两年多产生了近2000万的工单…

Django - 页面静态化和crontab定时任务(二)

一. 前言 一个网页会有很多数据是不需要经常变动的&#xff0c;比如说首页&#xff0c;变动频率低而访问量大&#xff0c;我们可以把它静态化&#xff0c;这样就不需要每次有请求都要查询数据库再返回&#xff0c;可以减少服务器压力 我们可以使用Django的模板渲染功能完成页面…

Amazon SageMaker:探索AI绘画云端部署新方案

目录 1 从艺术实验到AI绘画2 什么是Amazon SageMaker&#xff1f;3 云端部署AI绘画应用3.1 模型构建与部署3.2 AI绘画测试(文生图) 4 亚马逊云科技中国峰会 1 从艺术实验到AI绘画 在过去&#xff0c;人们只希望基于已有的给定数据做一些预测和拟合&#xff0c;因此判别式模型得…

怎么登录远程轻量云服务器?

​  轻量云服务器是一种基于云计算技术的服务器&#xff0c;具有价格低廉、配置灵活、易于管理等优点。但是&#xff0c;由于轻量云服务器通常是在云端运行&#xff0c;需要通过远程连接才能进行管理和操作。那么&#xff0c;怎么登录远程轻量云服务器呢? 要远程连接轻量云服…

JMeter测试笔记(五):JDBC请求

引言&#xff1a; 进行性能测试时&#xff0c;我们有时需要模拟数据库的访问和操作&#xff0c;而JMeter中的JDBC请求可以帮助我们实现这个目的。 在本文中&#xff0c;我们将深入了解JDBC请求的使用方式&#xff0c;并学习如何正确配置它们来模拟对数据库的访问和操作。 如…

C#,彩票数学——彩票预测是玄学还是数学?什么是彩票分析?怎么实现彩票号码的预测?

彩票原理系列文章 彩票与数学——彩票预测是玄学还是数学&#xff1f;https://mp.csdn.net/mp_blog/creation/editor/122517043彩票与数学——常用彩票术语的统计学解释https://mp.csdn.net/mp_blog/creation/editor/122474853彩票与数学——彩票缩水的数学概念与原理https://…

Codeforces Round 877 div2 C No Prime Differences

目录 一、题目 二、题目分析 三、 一、题目 传送门 C. No Prime Differences time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given integers n and m. Fill an n by m grid with the…

连杆滑块伸缩模组的制作

1. 运动功能说明 连杆滑块伸缩模组的主要运动方式为舵机带动滑块沿着光轴平行方向做伸缩运动。 2. 结构说明 本模组主要是由舵机、滑块、光轴、连杆等组成。 3. 电子硬件 在这个示例中&#xff0c;我们采用了以下硬件&#xff0c;请大家参考&#xff1a; 主控板 Basra主控板&…

java ssm贸易平台-物流管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java ssm贸易平台-物流管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主…

工业深度学习软件 从标注 训练 到测试 再到现场部署

工业深度学习软件 从标注 训练 到测试 再到现场部署 M7000技术规格表 Producer Specification 影像系统 Imaging Sys 适配相机 supported cameras 支持海康&#xff0c;迈德威视&#xff0c;度申2D相机&#xff08;可根据需求增加适配其他厂家相机&#xff09; Support for Hi…

为什么有了IP地址,还需要MAC地址呢?

不知道大家有没有困惑&#xff1a;为什么有了IP地址&#xff0c;还需要MAC地址呢&#xff1f;他们之间到底有什么联系&#xff1f;又有什么区别&#xff1f;是不是有一个是多余的&#xff1f; 流言传到了“IP地址”和“MAC地址”的耳朵里&#xff0c;他俩也非常苦恼&#xff0c…

php通过cURL爬取数据(2):CURLINFO_HTTP_CODE返回0

CURLINFO_HTTP_CODE返回0 一、项目说明二、curl_getinfo返回异常1.小鹅通SDK2.CURLINFO_HTTP_CODE为0的原因有哪些&#xff1f;3.返回CURLINFO_HTTP_CODE0的解决方案4.请求超时和服务器配置&#xff0c;CPU的使用率有关系吗5.结论 三、阿里云短信发送延迟后而集中发送1.发送集中…

【回眸】Python入门(五)基础语法列表和词典:Python如何消灭重复性劳动

前言 本篇博客为填坑篇&#xff0c;这个系列的上一篇竟然是2021年的9月30更新的&#xff0c;离谱&#xff0c;差点就到断更两周年纪念日了&#xff0c;后续逐渐走向填坑的每一天&#xff0c;继续创作&#xff0c;希望这个系列的专栏文章能帮助到更多有需要的人。 列表 什么是列…

操作系统的发展史(DOS/Windows篇)

█ DOS操作系统 20世纪70年代&#xff0c;伴随着计算机技术的成熟&#xff0c;操作系统也进入了一个快速发展阶段。现代操作系统的概念&#xff0c;也在那一时期逐渐形成。 1975年初&#xff0c;MITS电脑公司推出了基于Intel 8080芯片的Altair 8800微型计算机。这是人类历史上…

电子招标采购系统源码之从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。

统一供应商门户 便捷动态、呈现丰富 供应商门户具备内外协同的能力&#xff0c;为外部供应商集中推送展示与其相关的所有采购业务信息&#xff08;历史合作、考察整改&#xff0c;绩效评价等&#xff09;&#xff0c;支持供应商信息的自助维护&#xff0c;实时风险自动提示。…