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

news/2024/11/26 11:51:00/

目录

原文链接: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.ppmy.cn/news/292673.html

相关文章

粮油企业MES系统源码 粮油质量管控防伪溯源系统

粮油企业MES系统源码 粮油企业质量管控防伪溯源系统源码 粮油企业ERP系统源码 农产品MES系统源码 农产品溯源系统源码 利用物联网、云计算 、区块链、人工智能、5G等先进技术&#xff0c;结合特有的码码关联和RSA加密验证技术&#xff0c;开发的一套粮油质量管控防伪溯源系统&…

ARM简介及Cortex-A9

ARM ARM架构&#xff0c;又称先进精简指令集&#xff08;Advanced RISC Machine&#xff09;。ARM公司并不生产芯片&#xff0c;而是出售芯片技术授权。其合作公司针对不同需求搭配各类硬件部件&#xff0c;比如UART、SPI、I2C等&#xff0c;设计出不同的SoC芯片。 Cortex系列…

ARM——体系架构

1.ARM简介 ARM是Advanced RISC Machines的缩写&#xff0c;它是一家微处理器行业的知名企业&#xff0c;该企业设计了大量高性能、廉价、耗能低的RISC &#xff08;精简指令集&#xff09;处理器。公司的特点是只设计芯片&#xff0c;而不生产。它将技术授权给世界上许多著名的…

【直播预告】从A76到 A78——在变化中学习ARM微架构

伴随智能手机高速发展&#xff0c;处理器架构设计开发ARM公司几乎每年都更新CPU的核心架构。从2018年至2020年&#xff0c;ARM公司基于ARMv8架构推出了三代Cortex-A76、Cortex-A77、Cortex-A78 CPU内核架构。基于这几代CPU架构&#xff0c;芯片设计厂商也设计了多款性能优异的处…

从A76到A78——在变化中学习ARM微架构

一、引言 伴随智能手机的高速发展&#xff0c;移动处理器架构设计厂商ARM公司几乎每年都更新CPU的核心架构。从2018至2020年&#xff0c;ARM公司基于ARMv8架构推出了三代Cortex-A76、Cortex-A77、Cortex-A78经典CPU核心架构。基于这几代CPU架构&#xff0c;芯片设计厂商也设计了…

Tomcat的部署及优化(贼详细)

目录 一、Tomcat服务器简介 1、Tomcat服务器 2、Tomcat三大核心组件 3、 Java Servlet 4、JSP全称Java Server Pages 5、 Tomcat 功能组件结构 6、 Container 结构分析 7、Tomcat 请求过程 二&#xff1a;Tomcat部署与安装 1.关闭防火墙&#xff0c;上传所需软件包 2.安…

java公网对讲_出游通信新玩法 对讲机也能玩群聊

原标题&#xff1a;出游通信新玩法 对讲机也能玩群聊 来源标题&#xff1a;出游通信新玩法 对讲机也能玩群聊 国庆中秋佳节来临&#xff0c;不少人可能会选择出外游玩&#xff0c;联络沟通必不可少。几大运营商的一些通信产品可能会派上用场。近日&#xff0c;中国联通推出了联…

Aruba7010 默认密码_【对讲机的那点事】如何为您的数字对讲机热点配置安全密码...

点击上面微信号关注我关注我哟 定期推送对讲机行业资讯,华安捷讯对讲机公司的产品优惠等诸多优质内容,最接地气、重服务的对讲机行业微信平台!微信号:shuziduijiangji ID号:gh_778e0cd66ec0,关注我们妥妥没错!(广告合作:13051401525) BrandMeister是一款主服务器的操作…