2011-09-29 79 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