Qt QProcess基于Linux的命令管道符号无效问题【已解决】

QProcess基于Linux的命令管道符号无效问题

一、问题描述

  • 基于Linux环境,在Qt中使用QProcess start带管道符号|的命令,无异常但不会得到预期结果,将命令复制到终端中执行正常。代码如下所示:
bash 复制代码
    QString cmd = QString("命令1 | 命令2");
    qDebug() << cmd;
    process.start(cmd);

Linux管道符号|用于将前一个命令的输出作为后一个命令的输入,实现命令间的数据传递。它属于匿名管道(Anonymous Pipe),仅在内存中创建,作为临时通道,不依赖磁盘文件,且数据从左到右流动,不可逆向。管道主要用于组合简单命令,实现复杂的数据处理流程。

二、解决方案

2.1 问题原因

QProcess是Qt框架中用于启动外部程序并与它们交互的类,只能启动一个进程,输入"命令1 | 命令2",QProcess只能识别命令1,无法识别管道符号,会将| 命令2识别成命令1的参数。

2.2 解决方案

以下是解决方案:

    1. 调用bash,将上述代码的QString("命令1 | 命令2")替换为QString("bash -c \"命令1 | 命令2\"")
    1. 运行两次两次QProcess...
    1. QProcess进阶用法,使用process.setStandardOutputProcess(&xxx);函数

三、例程

3.1 解决方案例程

    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;
    }

}
    1. 调用两次QProcess,省略
    1. 使用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");
相关推荐
广州灵眸科技有限公司10 分钟前
为RK3588注入澎湃算力:RK1820 AI加速卡完整适配与评测指南
linux·网络·人工智能·物联网·算法
IT界的老黄牛16 分钟前
Linux 压缩命令实战:tar、gzip、bzip2、xz、zstd 怎么选?一篇讲清楚
linux·运维·服务器
IT WorryFree34 分钟前
飞塔防火墙与第三方设备进行IPSEC故障诊断期间,用户可能会观察到以下错误:
linux·服务器·网络
12345,catch a tiger1 小时前
虚拟机ubuntu安装Vmware Tools
linux·运维·ubuntu
凉、介1 小时前
别再把 PCIe 的 inbound/outbound、iATU 和 eDMA 混为一谈
linux·笔记·学习·嵌入式·pcie
辰风沐阳1 小时前
OpenClaw 安装教程(Ubuntu 24.04 Desktop)
linux·ubuntu
freshman_y1 小时前
Qtcreator怎么新建安卓项目?编写一个五子棋游戏APP?
android·qt
嘿嘿嘿x32 小时前
Linux记录过程
linux·开发语言
程序猿编码3 小时前
一个授予普通进程ROOT权限的Linux内核级后门:原理与实现深度解析
linux·运维·服务器·内核·root权限
小夏子_riotous3 小时前
openstack的使用——9. 密钥管理服务Barbican
linux·运维·服务器·系统架构·centos·云计算·openstack