我正在使用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();
问题在于管道("|"),并且进程没有任何回复.如果没有("|"),就像
"cat file"
一切都好.我试过smth.喜欢
"cat file \\| grep string", "cat file \| grep string"
但结果是一样的.如果我复制命令并在bash中运行它一切正常.
QString::toAscii().data()
和其他变换也有不好的结果.
快速而肮脏的黑客将是这样的:
QString cmd = "/bin/sh -c \"cat file | grep string\"";
你也可以避免使用C++ 11进行转义R""
,但重点是不要bash
在那里使用,因为这样只能使用bash.如果没有bash,只有ash或任何其他常见的桌面shell,它将无法在busybox中嵌入.
/bin/sh
通常是使用的shell解释器的符号链接,因此最终会起作用.
但!
我认为在使用Qt这样的高级C++/OOP框架时,你的想法太低了.当你从bash运行它时,我不建议以低级方式调用命令.这个用例有一些专用的高级便利API.
根据官方文档,QProcess应该适用于管道命令:
void QProcess :: setStandardOutputProcess(QProcess*destination)
将此过程的标准输出流管道传输到目标进程的标准输入.
换句话说,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中弃用.
问题是您无法使用QProcess运行系统命令,而只能运行单个进程.因此,解决方法是将您的命令作为参数传递给bash:
process.start("bash", QStringList() << "-c" << "cat file | grep string");