c++ - 带QProcess的C++ 管道( 或者命令链接)

  显示原文与译文双语对照的内容
99 3

我在使用Qt和 bash,需要执行类似下面这样的操作:


bash: cat file | grep string



在 Qt:


QString cmd ="cat file | grep string";


QProcess *process = new QProcess;


process->start(cmd);


process->waitForBytesWritten();


process->waitForFinished();


qDebug() <<process->readAll();



问题在于管道("|"),而进程returs没有任何问题。 如果没有("|"),就像

 
"cat file" 



 

一切正常我尝试了 smth 。 像


"cat file | grep string", 


"cat file | grep string" 



但结果是一样的。 如果我复制命令并在bash中运行它,一切都。


QString::toAscii().data()



其他转换也有错误的结果。

时间: 原作者:

137 2

问题是你不能使用QProcess运行系统命令,但是只有一个进程。 因此,解决办法是将你的命令作为参数传递给 bash:


process.start("bash", QStringList() <<"-c" <<"cat file | grep string");



136 4

快速和 dirty hack 将是:


QString cmd ="/bin/sh -c"cat file | grep string"";



你也可以避免在其中使用的转义,但是要点是不要在那里使用 bash,因为这将只使用 bash 。 它不会在没有 bash 。只是灰色。或者任何它的他公共桌面 shell的基础上嵌入。

/bin/sh 通常是使用 shell 解释器的符号符号,这样最终就可以工作了。

我想在使用高级 C++/oop框架时,你正在考虑的级别太低,比如 Qt 。 我不建议你在从bash运行它时以低级方式调用这些命令。 这个用例有一些专用的高级便利 API 。

基于官方文档,QProcess应该适用于管道的命令:

空心 QProcess::setStandardOutputProcess(QProcess * destination )

管道将这里进程的标准输出流传递到目标进程'标准输入 input 。

换句话说,可以通过以下方式实现 command1 | command2 shell 命令命令:


QProcess process1;


QProcess process2;



process1.setStandardOutputProcess(&process2);



process1.start("cat file");


process2.start("grep string");


process2.setProcessChannelMode(QProcess::ForwardedChannels);



//Wait for it to start


if(!process1.waitForStarted())


 return 0;



bool retval = false;


QByteArray buffer;


while ((retval = process2.waitForFinished()));


 buffer.append(process2.readAll());



if (!retval) {


 qDebug() <<"Process 2 error:" <<process2.errorString();


 return 1;


}



qDebug() <<"Buffer data" <<buffer;



这不是重点,而是一个有用的建议: 不要使用 QString::toAscii() 在 Qt 5中,该API已经被否决。

原作者:
...