我正在使用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();问题在于管道(“x”),而process returs则什么也没有。如果没有的话,就像
"cat file" 一切都很好。我试过了。喜欢
"cat file \\| grep string",
"cat file \| grep string" 但结果是一样的。如果我复制命令并在bash中运行它,一切都是正常的。
QString::toAscii().data()而其他的转换也有不好的结果。
发布于 2014-01-03 10:56:11
问题是您不能使用QProcess运行系统命令,而只能运行一个进程。因此,解决办法是将命令作为参数传递给bash:
process.start("bash", QStringList() << "-c" << "cat file | grep string");发布于 2014-01-03 10:55:38
快速而肮脏的黑客攻击是这样的:
QString cmd = "/bin/sh -c \"cat file | grep string\"";您还可以避免使用C++11的R""进行转义,但重点是不要在其中使用bash,因为这将使其只适用于bash。它不会在没有bash,只有灰,或者任何其他普通桌面外壳的情况下,与busybox一起工作。
/bin/sh通常是到所使用的shell解释器的符号链接,因此最终会工作。
但是!
我认为在使用高级C++/OOP框架(如Qt )时,您的想法有点过低。当您从bash运行命令时,我建议不要以低级的方式调用命令。对于这个用例,有一些专用的高级方便API。
基于正式文件,QProcess应该适用于管道的命令:
void::setStandardOutputProcess(QProcess*目的地) 将此进程的标准输出流管道到目标进程的标准输入。
换句话说,可以通过以下方式实现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()。该API在Qt 5中已被废弃。
发布于 2014-01-03 10:55:03
问题是,当您调用process->start(cmd)时,调用cat之后的命令都被解释为cat的参数,因此管道没有执行您期望的操作。如果首先使用字符串的参数调用bash,则应该得到所需的内容:-
QString cmd = "bash -c \"cat file | grep string\"";或者,您只需调用"cat文件“,并在读取来自QString的输出时对返回的QProcess进行搜索。
https://stackoverflow.com/questions/20901884
复制相似问题