命令在终端中工作,但不是通过 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() << "-c" << "ifconfig | grep inet");
【参考方案3】:
你似乎不能在 QProcess 中使用管道符号。
但是有 setStandardOutputProcess 方法将输出传递到下一个进程。
API 中提供了一个示例。
【讨论】:
以上是关于命令在终端中工作,但不是通过 QProcess的主要内容,如果未能解决你的问题,请参考以下文章
Maven 全新安装在 intellij 中工作,但不在终端中
Python plotly 在命令行中工作,但不在 python 文件中 - 导入错误
sbt dist在终端中工作但不与Jenkins一起作为shell脚本