如何在Qt中执行复杂的linux命令?

Nej*_*jat 8 c++ linux shell qt qprocess

我想通过在linux中运行命令来重启计算机QProcess.我在我的应用程序中对我的root密码进行了硬编码.

当我在终端中运行以下内容时,它可以完美运行:

echo myPass | sudo -S shutdown -r now 
Run Code Online (Sandbox Code Playgroud)

当我将命令放在shell脚本中并通过QProcess它调用它也是成功的:

QProcess process;
process.startDetached("/bin/sh", QStringList()<< "myScript.sh");
Run Code Online (Sandbox Code Playgroud)

但我无法通过直接传递到QProcess:

process.startDetached("echo myPass | sudo -S shutdown -r now ");
Run Code Online (Sandbox Code Playgroud)

它只会打印 myPass | sudo -S shutdown -r now

如何直接使用这些相对复杂的命令QProcess.(没有放入shell脚本).

lpa*_*app 10

为此目的存在的关键方法建立在QProcess:

void QProcess :: setProcessChannelMode(ProcessChannelMode mode)

void QProcess :: setStandardOutputProcess(QProcess*destination)

因此,以下代码片段将是等同于command1 | command2不限制自己的一个或另一个解释器:

QProcess process1
QProcess process2;

process1.setStandardOutputProcess(&process2);

process1.start("echo myPass");
process2.start("sudo -S shutdown -r now");
process2.setProcessChannelMode(QProcess::ForwardedChannels);

// Wait for it to start
if(!process1.waitForStarted())
    return 0;

bool retval = false;
QByteArray buffer;
// To be fair: you only need to wait here for a bit with shutdown,
// but I will still leave the rest here for a generic solution
while ((retval = process2.waitForFinished()));
    buffer.append(process2.readAll());

if (!retval) {
    qDebug() << "Process 2 error:" << process2.errorString();
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

您可以删除该sudo -S部分,因为您可以以root身份运行此小程序,以及设置权限.你甚至可以为关机程序设置setuid或setcap.

我们在构建商业Linux系统时通常做的是拥有一个最小的应用程序,可以为它正在尝试的活动获取setuid或setcap,然后我们在Linux 上system(3)QProcess在Linux上显式调用它.基本上,

我会编写这个小应用程序以避免对整个应用程序提供完全root权限,因此限制访问权限以防止恶意使用,如下所示:

sudo chmod u+s /path/to/my/application
Run Code Online (Sandbox Code Playgroud)