我需要强制我的c ++ QT4应用程序从linux命令读取结果。我正在尝试使用Qprocess,但是一旦我的命令变得复杂,它就会以某种方式混乱(只是猜测)并且不起作用。
在这里,我尝试为yu做一个小例子:
QProcess process;
command = "ls -l | grep a | sort";
qDebug() << "Execute command -> "+command;
process.start( command );
process.waitForFinished(-1);
QString processStdout = process.readAllStandardOutput();
QString processStderr = process.readAllStandardError();
qDebug() << "Std out -> "+processStdout;
qDebug() << "Std err -> "+processStderr;
这将打印:
Execute command -> ls -l | grep a | sort
"Std out -> "
"Std err -> ls: |: No such file or directory
如果从consol中删除,则会正确打印文件名。
如果我用更简单的问题command = "ls -l";
取代comman,它可以顺利工作
操作系统在标准错误时返回错误。
因此,我猜测用于该命令的Qstring以某种方式被操纵。关于wht发生的任何想法?
答案 0 :(得分:7)
QProcess
不支持shell命令。因此,管道符号不会被shell解释,而是直接传递给ls
。 ls
将其解释为文件名,并抱怨,因为显然没有名为|
的文件。
您需要通过重定向QProcess对象的输入和输出流来手动设置管道。阅读文档以了解如何执行此操作。
一般来说应该如何避免shell命令,而是依赖于Qt类和函数。当然不需要致电grep
或ls
,因为使用QRegExp
和QDir
可以更轻松地完成相同操作。如果需要执行子进程,则使用::start(const QString&, const QStringList&, OpenMode)
重载并将所有参数作为列表传递,以避免引用问题。
答案 1 :(得分:3)
试试这个:
从QProcess运行shell并将参数传递给shell。示例:
QStringList options;
options << "-c" << "ls -l | grep a | sort";
QProcess process;
process.start("/bin/sh", options); //Use sh or another shell
让我知道这是否有效。
答案 2 :(得分:0)
command = "ls -l | grep a | sort";
实际上不是一个流程,而是三个不同流程的流水线:ls,grep和sort。
答案 3 :(得分:-1)
感谢所有人的帮助。
为了做我需要的事情,我必须使用以下方法来改变方法:
std::string cmd("/sbin/ifconfig eth0");
FILE* pfd = popen(cmd.c_str(), "r");
if (pfd)
{
while (!feof(pfd))
{
char buf[1024] = {0};
if (fgets(buf, sizeof(buf), pfd) > 0)
{
std::cout << "buf = " << buf; // a newline is already present
}
}
pclose(pfd);
}