2011-09-29 82 views
3

我需要强制我的C++ QT4应用程序从linux命令读取结果。我正在尝试使用Qprocess,但一旦我的命令变得复杂,它就会以某种方式被弄乱(只是猜测)并且不起作用。Qprocess混淆我的Linux命令(我认为)。怎么修?

在这里,我试图做出宇一个小例子:

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符文。

如果我用一些简单的东西替换comman,例如command = "ls -l";,它将无法正常工作 该错误是由操作系统在标准错误上返回的。

因此,我猜测用于该命令的Qstring会以某种方式被操纵。有关这种事情发生的任何想法?

回答

7

QProcess不支持shell命令。管道符号因此不被shell解释,而是直接传递给lsls将其解释为文件名,并抱怨,因为通常没有名为|的文件。

您需要手动设置管道,方法是重定向QProcess对象的输入和输出流。阅读文档以了解如何执行此操作。

一般应该如何避免shell命令,而是依赖于Qt类和函数。肯定不需要拨打grepls,因为使用QRegExpQDir可以更容易完成。如果您需要执行子进程,则使用重载并将所有参数作为列表传递以避免引用问题。

+0

我不认为它只是|。如果我使用命令egrep -l'aaa'/ user/*/mydir/*说egrep:/ user/*/mydir/*没有这样的文件或目录。 和在这个命令我没有| – Stefano

+3

同样的问题。 *通配符也由shell解释。在shell上发生的事情是,通配符被替换,并且命令被所有匹配的文件调用。如果使用QProcess,则不会执行这样的替换,并且grep被称为egrep“/ user/*/mydir/*”(注意“,即该模式作为参数给予egrep)。你也会遇到同样的问题。 – LiKao

+0

现在我明白了。非常感谢! – Stefano

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 

让我知道这是否奏效。

0
command = "ls -l | grep a | sort"; 

实际上并不是一个进程,而是3个不同进程的管道:ls,grep和sort。

-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); 
} 
+1

-1。'QProcess'完全可以做到这一点,不需要使用C函数。 – lunaryorn

+0

如果这个答案解决了你的问题,你应该接受它,而不是接受另一个。 – 2013-05-15 04:58:13