我想通过使用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脚本)。
答案 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执行sh
或bash
,并将shell脚本作为参数,因为您的命令包含|
,必须< / em>由sh
或bash
解释。
然而,这只是我的看法,但是:我认为这不是一个很好的解决方案,可以做你正在做的事情,即在可执行文件中包含root密码。