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

时间:2014-04-27 11:21:23

标签: c++ linux qt shell qprocess

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

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

echo myPass | sudo -S shutdown -r now 

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

QProcess process;
process.startDetached("/bin/sh", QStringList()<< "myScript.sh");

但我无法通过直接转到QProcess来运行它:

process.startDetached("echo myPass | sudo -S shutdown -r now ");

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

如何直接使用QProcess运行此类相对复杂的命令。 (没有放入shell脚本)。

3 个答案:

答案 0 :(得分: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;
}

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

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

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

QProcess

答案 1 :(得分:2)

首先,您可以配置sudo以避免询问密码。例如,成为sudo组的成员并拥有该行

 %sudo  ALL=NOPASSWD:  ALL

/etc/sudoers文件中。当然,不要求密码会降低系统的安全性。

要回答关于Qt的问题,请记住bash(1)与所有Posix shell一样,因此/bin/sh,接受带有字符串的-c参数(实际上{{3}分支/bin/sh -c)。所以只需执行

 process.startDetached("/bin/sh", QStringList()<< "-c" 
                       << "echo myPass | sudo -S shutdown -r now");

作为system(3),将root密码放在可执行文件中是一个坏主意。

答案 2 :(得分:1)

您必须将命令放在shell脚本中并使用QProcess执行shbash,并将shell脚本作为参数,因为您的命令包含|必须< / em>由shbash解释。

然而,这只是我的看法,但是:我认为这不是一个很好的解决方案,可以做你正在做的事情,即在可执行文件中包含root密码。