【问题标题】:Command working in terminal, but not via QProcess命令在终端中工作,但不是通过 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' 的任何技巧,例如将 \' 用于 '\| 用于 |?对于特殊字符?但我也试过了:(

【问题讨论】:

标签: c++ linux qt terminal pipe


【解决方案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 中提供了一个示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 2016-09-09
    • 1970-01-01
    相关资源
    最近更新 更多