QProcess基于Linux的命令管道符号无效问题
- 一、问题描述
- 二、解决方案
-
- [2.1 问题原因](#2.1 问题原因)
- [2.2 解决方案](#2.2 解决方案)
- 三、例程
-
- [3.1 解决方案例程](#3.1 解决方案例程)
- [3.2 官方例程](#3.2 官方例程)
一、问题描述
- 基于Linux环境,在Qt中使用
QProcessstart带管道符号|的命令,无异常但不会得到预期结果,将命令复制到终端中执行正常。代码如下所示:
bash
QString cmd = QString("命令1 | 命令2");
qDebug() << cmd;
process.start(cmd);
Linux管道符号
|用于将前一个命令的输出作为后一个命令的输入,实现命令间的数据传递。它属于匿名管道(Anonymous Pipe),仅在内存中创建,作为临时通道,不依赖磁盘文件,且数据从左到右流动,不可逆向。管道主要用于组合简单命令,实现复杂的数据处理流程。
- Linux命令之通配符&管道符:https://cloud.tencent.com/developer/article/2356665
- Linux进程间通信------匿名管道:https://cloud.tencent.com/developer/article/2468685
- 深入解析Linux匿名管道机制与应用:https://blog.csdn.net/2302_80871796/article/details/149539214
二、解决方案
2.1 问题原因
QProcess是Qt框架中用于启动外部程序并与它们交互的类,只能启动一个进程,输入"命令1 | 命令2",QProcess只能识别命令1,无法识别管道符号,会将| 命令2识别成命令1的参数。
2.2 解决方案
以下是解决方案:
-
- 调用bash,将上述代码的
QString("命令1 | 命令2")替换为QString("bash -c \"命令1 | 命令2\"")
- 调用bash,将上述代码的
-
- 运行两次两次QProcess...
-
- QProcess进阶用法,使用
process.setStandardOutputProcess(&xxx);函数
- QProcess进阶用法,使用
- QProcess使用命令管道符号:https://wenku.csdn.net/answer/2qx6r9o56m
- 使用QProcess的管道(或命令链):https://cloud.tencent.com/developer/ask/sof/110441190
三、例程
3.1 解决方案例程
-
- 调用bash
cpp
#include <QCoreApplication>
#include <QProcess>
#include <QDebug>
int main(int argc, char *argv[])
{
QProcess process;
QString tar_cmd = QString("bash -c \"cat Makefile | grep LIB > cs.txt \"");
qDebug() << tar_cmd;
process.start(tar_cmd);
if (!process.waitForStarted()){
qDebug() << "start failed";
return false;
}
if (!process.waitForFinished(-1)){
qDebug() << "run failed" << process.errorString();
return false;
}
}
-
- 调用两次QProcess,省略
-
- 使用
process.setStandardOutputProcess(&xxx);函数
- 使用
cpp
#include <QCoreApplication>
#include <QProcess>
#include <QDebug>
int main(int argc, char *argv[])
{
QProcess process1;
QProcess process2;
process1.setStandardOutputProcess(&process2);
process1.start("cat Makefile");
process2.setProcessChannelMode(QProcess::ForwardedChannels);
process2.start("bash -c \"grep LIB > cs.txt\"");
if(!process1.waitForStarted())
return 0;
process1.waitForFinished();
process2.waitForFinished();
}
3.2 官方例程
官方文档:void QProcess::setStandardOutputProcess(QProcess *destination) -
这个函数是在Qt 4.2中引入
- 将此进程的标准输出流通过管道传输到目标进程的标准输入。
带管道的Shell命令command1 | command2,可以使用QProcess通过以下代码完成:
cpp
QProcess process1;
QProcess process2;
process1.setStandardOutputProcess(&process2);
process1.start("command1");
process2.start("command2");