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

news2024/11/29 5:32:08

目录

原文链接: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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

接口抓包分析与Mock实战

这里写目录标题 一、知识点梳理1、接口抓包需要具备的能力2、接口抓包原理 二、Charles 基础使用三、charles抓包分析四、Charles 使用1、过滤&#xff1a;Filter、Focus2、重发&#xff1a;Repeat、Repeat Advanced3、修改请求&#xff1a;Compose4、弱网&#xff1a;Throttle…

实验3 Tomasulo算法【计算机系统结构】

实验3 Tomasulo算法【计算机系统结构】 前言推荐实验3 Tomasulo算法1 实验目的2 实验平台3 实验内容和步骤4 实验总结与心得 最后 前言 2023-6-9 9:19:50 以下内容源自《【计算机系统结构】》 仅供学习交流使用 推荐 实验2 指令调度和延迟分支【计算机系统结构】 实验3 To…

webgpu之旅03

19854902 319854902 319854902 319854902 webgpu交Q流群我们找个例子看看别人的renderer three.js v152 首先init函数 看见中间有个对象 WebGPURenderPipelines 跟进去看看 这个构造函数里可以看见有这么些数据 get( renderObject ) {const device this.device;const cache …

Meetup 报名|06.17 StarRocks Friends 与你相约上海

StarRocks & Friends 是由 StarRocks 社区发起的城市线下 meetup&#xff0c;旨在联合社区与行业的专家小伙伴们分享基于 StarRocks 的最佳实践、大数据分析的前沿技术和 StarRocks 生态融合等热门话题。 不远千里奔赴&#xff0c;只为与你相聚。这个夏天&#xff0c;让我们…

Vue+springboot小区居民外出登记信息管理系统

系统采用更加便于维护和使用的JAVA语言&#xff0c;其可拓展性高且更富于表现力&#xff0c;方便基本信息、外出申请、健康信息、外来人员等功能。通过Spring Boot框架来进行网页编程&#xff0c;其方便易用、移植适用性广、更加安全可靠。数据库方面则选用的是体积小、速度快、…

【安装教程】Win10上安装Microsoft To-Do客户端(手机端)

这里写自定义目录标题 操作方法操作说明辅助疑难问题 操作方法 此方法是应用于微软商店无法安装、安装不成功等情况 操作说明 原文&#xff1a;手把手教你在Win10上安装Microsoft To-Do客户端:https://www.jianshu.com/p/32a1ea417cba 1.访问微软网站&#xff0c;找到To-Do的…

【深入浅出 Spring Security(七)】RememberMe的实现原理详讲

RememberMe 的实现原理 一、RememberMe 的基本使用二、RememberMeAuthenticationFilter 源码分析RememberMeServicesTokenBasedRememberMeServicesTokenBasedRememberMeServices 中对 processAutoLoginCookie 方法的实现总结原理图式 三、提高安全性PersistentTokenBasedRememb…

【数据分析之道-Matplotlib(八)】Matplotlib箱线图

文章目录 专栏导读1、Matplotlib箱线图boxplot()基本语法2、Matplotlib箱线图boxplot()举例异常值3、Matplotlib箱线图boxplot()样式定义4、Matplotlib箱线图boxplot()举例带缺口5、Matplotlib箱线图boxplot()举例横向显示6、Matplotlib箱线图boxplot()举例显示平均值7、Matplo…

电子企业实施数字化工厂建设之前,需要注意哪些

随着工业4.0时代的到来&#xff0c;数字化工厂建设已成为越来越多电子企业的重要议题。数字化工厂管理系统能够提高生产效率、降低成本、提高产品质量等多个方面的优势&#xff0c;对于企业的可持续发展具有重要意义。然而&#xff0c;在实施电子企业数字化工厂建设之前&#x…

【Flutter】widgets (6) Stateful Widget 有状态组件的生命周期

文章目录 一、前言二、StatefulWidget的生命周期三、State对象的生命周期四、initState(), didUpdateWidget(), dispose()方法的用途五、StatefulWidget和State对象的生命周期六、代码示例七、总结一、前言 在上一篇文章中,我们初步认识了什么是Stateful Widget 有状态组件。…

minigpt4 部署踩坑记录

1&#xff0c;最近看网上minigpt4很火&#xff0c;下载下来试一下&#xff0c;把碰到问题记录一下。 2 访问 GitHub - Vision-CAIR/MiniGPT-4: MiniGPT-4: Enhancing Vision-language Understanding with Advanced Large Language Models 下载代码到 centos服务上。 3&#xf…

九耶丨阁瑞钛伦特-大型计算机硬件组成(一)

​ IBM大型机系统是由主机和多种外围设备组合形成的一个综合系统&#xff0c;上面是一个主机系统组成的例子。 ​以上是OS390操作系统的组成情况&#xff1a; MVS&#xff1a; 大型机操作系统的核心部分&#xff0c;有时又被使用为大型机操作系统的全称。 SMS&#xff1a; S…

文件管理开发指南全新登场,快来了解如何访问各类文件

原文&#xff1a;文件管理开发指南全新登场&#xff0c;快来了解如何访问各类文件&#xff0c;点击链接查看更多技术内容。 在应用开发的过程中&#xff0c;我们经常会用到各种各样的文件&#xff0c;例如文档、图片、音频、视频等&#xff0c;如何管理和访问这些文件&#xff…

【网络】· VTP虚拟局域网中继

目录 &#x1f349;VTP技术 &#x1f349;以太网通道配置 &#x1f352;sw1配置 &#x1f352;sw2配置 &#x1f349;VTP工作原理 &#x1f352;VTP模式 &#x1f352;VTP通告 &#x1f352;VTP的版本 &#x1f352;VTP修改编号 &#x1f352;VTP通告类型 &#x1f352;VTP修剪…

数据分析第16课seaborn可视化

FacetGrid与调色盘(参看语雀) 前言:有针对性的,选择不同的分析方式去整合数据,描述统计学: 对比分析:同期对比,环境对比等。分类分析:字段分为哪些类别,每个类别出现了多少次,哪个类别的权重是最大的。哪个类别是可以忽略的。哪个类别是干扰项。分布分析:例如身高,…

实现一个简单的事件驱动处理框架

点击上方“嵌入式应用研究院”&#xff0c;选择“置顶/星标公众号” 干货福利&#xff0c;第一时间送达&#xff01; 来源 | 嵌入式应用研究院 整理&排版 | 嵌入式应用研究院 事件驱动框架允许程序处理外部事件&#xff0c;如网络连接、文件I/O、超时和信号。事件驱动框架可…

配置office和wps的数学公式编辑工具Mathtype7.4

一、概述 《数学公式编辑器(MathType)》 是一款专业的数学公式编辑工具&#xff0c;理科生专用的工具。mathtype公式编辑器能够帮助用户在各种文档中插入复杂的数学公式和符号。 数学公式编辑器工具可以轻松输入各种复杂的公式和符号&#xff0c;与Office文档完美结合&#xff…

imu预积分处理

VINS-Mono是HKUST的Shen Shaojie团队开源的一套非常优秀的Visual-Inertial融合定位算法。关于算法的介绍以及论文可以通过此链接查看。 IMU、ˆω和ˆa的原始陀螺仪和加速度计测量值由下式给出&#xff1a; 在车身坐标系测量的IMU测量结合了抗重力和平台动力学的力&#xff0c…

[蓝桥杯 2018 国 B] 矩阵求和

题目描述 经过重重笔试面试的考验&#xff0c;小明成功进入 Macrohard 公司工作。 今天小明的任务是填满这么一张表&#xff1a; 表有 n 行 n 列&#xff0c;行和列的编号都从 1 算起。 其中第 ii 行第 jj 个元素的值是 gcd(i,j) 的平方&#xff0c;gcd 表示最大公约数&#xf…

什么样的电容笔好用?好用的平板触控笔

现在使用电容笔的人越来越多了&#xff0c;尤其学生党和上班族&#xff0c;可以使用电容笔来提高生产效率&#xff0c;这个时候电容笔的书写流畅度就非常重要&#xff0c;今天给大家介绍四款平价又好用的电容笔。跟我来看看吧&#xff01; 一、使用电容笔的用途&#xff1a; …