在C++中使用QProcess重定向gnome终端的输出

Redirecting output from gnome-terminal using QProcess in C++

本文关键字:gnome 终端 输出 重定向 QProcess C++      更新时间:2023-10-16

我正在尝试为gui生成一个子流程,该子流程将生成一个终端。我希望这个终端产生的数据(stdout和stderr)显示在出现的窗口上,并显示在一个设置的日志文件中。当我直接在shell中键入命令时,它会按预期工作,但当作为启动命令提供给QProcess时,它实际上不会向文件中写入任何内容。

例如:如果用户没有安装二进制文件,则应将找不到命令的信息写入bin.log。我已经为派生的QProcess设置了与正在运行的父进程相同的环境(这样它就可以找到bash和其他任何东西),并在调用QProcess.start()方法之前设置了工作目录。我写了一个测试用例如下:

gnome-terminal --title 'Sub-Terminal' -e 'bash -c "foo [args to foo] |& tee foo.log"'

在Qt中,我执行以下操作:

QProcess *child = new QProcess(this);
QString   cmd   = "gnome-terminal --title 'Sub-Terminal' -e 'bash -c "foo [args to foo] |& tee foo.log"'";
child->setProcessEnvironment(<process environment I have created before>);
child->setWorkingDirectory(<current working dir>);
child->start(cmd);
...

它生成终端,但不向foo.log写入任何数据

QProcess *child = new QProcess(this);
QString   prog  = "gnome-terminal"
QStringList args;
args << "-x" << "bash" << "foo" << "[foo's arguments]" << "|&" << "tee" << "foo.log";
// set the process env and working dir
child->start(prog, args);

有人对如何解决这个问题有什么建议吗?我尝试过使用QProcess.setStandardErrorFile(foo.log)和QProcess.sedStandardOutputFile(foo.log)重定向stdout和stderr,但这似乎是从gnome终端本身重定向stdout(这不是什么)。

您必须在"-e"之后将要在终端中执行的整个命令作为单个参数提供给QProcess,以及将要在bash中执行的命令作为单个变量提供给bash:

args << "-e" << "bash -c 'foo [args to foo] |& tee foo.log'";

这基本上执行

bash -c 'foo [args to foo] |& tee foo.log'

在终端中,它自己执行

foo [args to foo] |& tee foo.log

bash内。

您的猜测是正确的,即读取gnome-terminal过程的输出不起作用。