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()

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

时间:原作者:0个回答

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已经被否决。

原作者:
...