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

Sca*_*ode 19 c++ linux terminal qt pipe

ifconfig | grep 'inet'
Run Code Online (Sandbox Code Playgroud)

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

我的示例代码是

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

textedit上没有显示任何内容.

但是当我ifconfig在qprocess开始使用时,输出会显示在textedit上.我错过任何计谋构建命令ifconfig | grep 'inet',如使用\''\||?特殊字符?但我也试过了:(

lee*_*mes 41

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

有三种可能的解决方案:

将要执行的命令作为参数添加到shafter -c("command"):

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

sh.waitForFinished();
QByteArray output = sh.readAll();
sh.close();
Run Code Online (Sandbox Code Playgroud)

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

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

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

sh.waitForFinished();
QByteArray output = sh.readAll();
sh.close();
Run Code Online (Sandbox Code Playgroud)

另一种避免的方法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();
Run Code Online (Sandbox Code Playgroud)

  • 我添加了一些可能解决方案的代码示例. (5认同)
  • Grep工作.但我想把ifconfig的输出传递给awk'/inet/{worub(/.*:/,"",$ 1); print $ 1}'.它成功地在终端上打印了一些o/p而不是通过Qprocess.我用你的解决方案2 (2认同)
  • 我相信第二个例子是错误的:如果启动 shell 并向其写入,您还需要 (1) 通过添加换行符向 shell 发送命令,以及 (2) 在执行 `grep` 命令后终止 shell,或者 ` waitForFinished()` 将永远等待。我做了一个快速测试来验证您的代码是否有效,但它不适合我,但如果我错了,请纠正我:) (2认同)
  • @AkiRoss非常感谢你的投入,你是对的.(2):我猜问题是`sh`等待stdin上的更多命令.你应该在写和等待之间用`sh.closeWriteChannel()`关闭sh的stdin通道.(1):我95%确定`\n`不是必需的.(1)+(2):如果你*不*关闭stdin,并且*不*写一个换行符,似乎什么也没发生.如果你这样做,那么执行命令,但只有关闭sh的stdin才会在执行后关闭.因此,如果我们解决(2),我们不需要关心(1).如果我们想要执行多个命令,我们应该修复(1)而不是(2). (2认同)

kmk*_*lan 8

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

p1.start("/bin/sh -c \"ifconfig | grep inet\"");
Run Code Online (Sandbox Code Playgroud)

  • 替代方案(更安全,因为你不必注意在参数内转义,如果它更复杂):使用QStringList作为参数,如:`p1.start("/ bin/sh",QStringList()<< "-c"<<"ifconfig | grep inet");` (4认同)

Ber*_*nnF 5

您似乎无法在QProcess中使用管道符号.

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

API中提供了一个示例.