命令在终端中工作,但不是通过 QProcess

Posted

技术标签:

【中文标题】命令在终端中工作,但不是通过 QProcess【英文标题】:Command working in terminal, but not via QProcess 【发布时间】:2012-05-28 21:54:38 【问题描述】:
ifconfig | grep 'inet'

通过终端执行时正在工作。但不是通过 QProcess

我的示例代码是

QProcess p1;
p1.start("ifconfig | grep 'inet'");
p1.waitForFinished();
QString output(p1.readAllStandardOutput());
textEdit->setText(output);

textedit 上没有显示任何内容。

但是当我在 qprocess 开始时只使用 ifconfig 时,输出会显示在 textedit 上。我是否错过了构造命令 ifconfig | grep 'inet' 的任何技巧,例如将 \' 用于 '\| 用于 |?对于特殊字符?但我也试过了:(

【问题讨论】:

您需要为 ifconifg 指定完整路径。你的应用程序有不同的 PATH 变量然后你终端 @KamilKlimek 因为这可能是单个命令的问题,在这种情况下,命令管道(QProcess 不支持)是真正的问题。 对!完全忘记了那个 如果要获取ipaddress,请使用正确的方式:qt-project.org/doc/qt-4.8/qnetworkinterface.html Qprocess messes my linux command up (i think). how to fix?的可能重复 【参考方案1】:

QProcess 执行一个单一的进程。您要做的是执行 shell 命令,而不是进程。命令管道是 shell 的一个特性。

有三种可能的解决方案:

-c(“command”)之后将您要执行的命令作为参数放入sh

QProcess sh;
sh.start("sh", QStringList() << "-c" << "ifconfig | grep inet");

sh.waitForFinished();
QByteArray output = sh.readAll();
sh.close();

或者您可以将命令作为标准输入写入sh

QProcess sh;
sh.start("sh");

sh.write("ifconfig | grep inet");
sh.closeWriteChannel();

sh.waitForFinished();
QByteArray output = sh.readAll();
sh.close();

另一种避免sh 的方法是启动两个QProcesses 并在您的代码中进行管道处理:

QProcess ifconfig;
QProcess grep;

ifconfig.setStandardOutputProcess(&grep); // "simulates" ifconfig | grep

ifconfig.start("ifconfig");
grep.start("grep", QStringList() << "inet"); // pass arguments using QStringList

grep.waitForFinished(); // grep finishes after ifconfig does
QByteArray output = grep.readAll(); // now the output is found in the 2nd process
ifconfig.close();
grep.close();

【讨论】:

Grep 工作。但我想将 ifconfig 的输出通过管道传输到 awk '/inet/gsub(/.*:/,"",$1);print$1'。它成功地在终端上打印了一些 o/p,而不是通过 Qprocess。我用了你的解决方案 2 你应该更喜欢第三种方法。对于复杂的参数,您应该使用 QStringList 传递它们,就像我在第一个示例中所做的那样。我会更新第三种方法给你一个想法。 我相信第二个例子是错误的:如果你启动 shell 并写入它,你还需要 (1) 通过添加换行符向 shell 发送命令和 (2) 在grep 命令已执行,或者 waitForFinished() 将永远等待。我做了一个快速测试来验证你的代码是否有效,但它不适合我,但如果我弄错了,请纠正我:) @AkiRoss 非常感谢您的意见,您是对的。 (2):我猜问题是sh 在标准输入上等待更多命令。您应该在写入和等待之间用sh.closeWriteChannel() 关闭sh 的标准输入通道。 (1):我 95% 确定 \n 是不必要的。 (1)+(2):如果你 not 关闭标准输入,并且not 写一个换行符,似乎什么都没有发生。如果您这样做,则执行命令,但只有关闭 sh 的标准输入才会在执行后关闭 sh。所以如果我们解决了(2),我们就不需要关心(1)了。如果我们想执行多个命令,我们应该修复 (1) 而不是 (2)。 @AkiRoss 关闭标准输入还将执行“最后一行”的内容。只需在终端中尝试:echo -n 'ifconfig | grep inet' | sh,其中echo -n 省略换行符。然而它会在之后终止,并且 echo 和 sh 之间的管道将关闭 sh 的标准输入流。【参考方案2】:

QProcess 对象不会自动为您提供完整的 shell 语法:您不能使用管道。为此使用外壳:

p1.start("/bin/sh -c \"ifconfig | grep inet\"");

【讨论】:

啊,是的,应该是双引号,不是引号。 替代(更安全,因为您不必注意在参数中转义,如果它更复杂):使用 QStringList 作为参数,如下所示:p1.start("/bin/sh", QStringList() &lt;&lt; "-c" &lt;&lt; "ifconfig | grep inet");【参考方案3】:

你似乎不能在 QProcess 中使用管道符号。

但是有 setStandardOutputProcess 方法将输出传递到下一个进程。

API 中提供了一个示例。

【讨论】:

以上是关于命令在终端中工作,但不是通过 QProcess的主要内容,如果未能解决你的问题,请参考以下文章

无法让 subl 命令在 OSX 终端中工作 [重复]

Maven 全新安装在 intellij 中工作,但不在终端中

Python plotly 在命令行中工作,但不在 python 文件中 - 导入错误

sbt dist在终端中工作但不与Jenkins一起作为shell脚本

Codeigniter CLI 在终端中工作,而不是在 Cpanel cron 中

应用程序在 iPad 中崩溃但在 iPad 模拟器中工作正常