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

How to execute complex linux commands in Qt?

本文关键字:复杂 linux 命令 执行 Qt      更新时间:2023-10-16

我想使用QProcess在linux中运行一个命令来重新启动计算机。我已经在我的应用程序中硬编码了我的根密码。

当我在终端中运行以下程序时,它运行得很完美:

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脚本)。

QProcess:中为此目的而存在的关键方法

void QProcess::setProcessChannelMode(ProcessChannelMode模式)

void QProcess::setStandardOutputProcess(QProcess*目的地)

因此,以下代码片段将等效于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,然后我们在Linux上用system(3)QProcess显式地调用它。基本上,

我会写那个小应用程序,以避免对整个应用程序进行完全的root访问,从而限制访问权限以防止恶意使用,如下所示:

sudo chmod u+s /path/to/my/application

首先,您可以配置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");

正如AntiClimacus所回答的那样,将根密码放在可执行文件中是个坏主意。

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

然而,这只是我的观点,但是:我不认为这是一个好的解决方案来做你正在做的事情,即在可执行文件中包括你的根密码。