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

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

当我在terminal中运行以下它完美的作品:

 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 myPass | sudo -S shutdown -r now

如何直接使用QProcess来运行这样相对复杂的命令? (不要把一个shell脚本)。

Solutions Collecting From Web of "如何在Qt中执行复杂的Linux命令?"

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

void QProcess :: setProcessChannelMode(ProcessChannelMode mode)

void QProcess :: setStandardOutputProcess(QProcess * destination)

因此,下面的代码片段将是command1 | command2的等价 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)或Linux上的QProcess明确地调用它。 基本上,

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

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

首先,你可以配置sudo避免询问你的密码。 例如作为sudo组的成员和sudo

  %sudo ALL=NOPASSWD: ALL 

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

为了回答你关于Qt的问题,记住bash(1)像所有的posix shell(因此/bin/sh )接受带有字符串的-c参数(实际上system(3)是分支/bin/sh -c )。 所以只要执行

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

正如AntiClimacus回答的 ,把你的root密码放在一个可执行文件中是一个坏主意。

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

但是,这只是我的意见,但是:我不认为这是一个很好的解决方案,你正在做什么,即包括你的根密码在一个可执行文件。