web-dev-qa-db-ja.com

Qtで複雑なLinuxコマンドを実行する方法は?

QProcessを使用してLinuxでコマンドを実行し、コンピューターを再起動したいと思います。アプリケーションにrootパスワードをハードコーディングしました。

ターミナルで以下を実行すると、完全に機能します。

echo myPass | Sudo -S shutdown -r now 

コマンドをシェルスクリプトに入れて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を使用して、このような比較的複雑なコマンドを直接実行するにはどうすればよいですか。 (シェルスクリプトを入れない)。

8
Nejat

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;
}
_

この小さなプログラムをrootとして実行したり、権限を設定したりできるため、_Sudo -S_の部分を削除できます。シャットダウンプログラムにsetuidまたはsetcapを設定することもできます。

商用Linuxシステムを構築するときに通常行うことは、実行しようとしているアクティビティに対してsetuidまたはsetcapを取得できる最小限のアプリケーションを用意することです。次に、Linuxではsystem(3)またはQProcessを使用して明示的に呼び出します。基本的に、

アプリケーション全体へのフルルートアクセスを許可しないように、その小さなアプリケーションを作成します。そのため、次のように悪意のある使用に対してアクセス権を制限します。

_Sudo chmod u+s /path/to/my/application
_
10
lpapp

まず、Sudoを設定して、パスワードを尋ねられないようにすることができます。たとえば、Sudoグループのメンバーであり、次の行を持つことによって

 %Sudo  ALL=NOPASSWD:  ALL

/etc/sudoersファイル内。もちろん、パスワードを要求しないと、システムのセキュリティが低下します。

Qtに関する質問に答えるには、 bash(1) 、すべての Posix シェル、つまり/bin/shと同様に、-c引数を文字列(実際には system(3)/bin/sh -cをフォークしています)。だから実行するだけ

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

AntiClimacusが回答 のように、実行可能ファイル内にrootパスワードを入れることは悪い考えです。

コマンドに|が含まれているため、コマンドをシェルスクリプトに配置し、QProcessを引数としてshまたはbashを実行する必要がありますmustshまたはbashによって解釈されます。

ただし、これは私の意見ですが、実行可能ファイルにrootパスワードを含めるなど、実行していることを実行するのは良い解決策ではないと思います。

1
AntiClimacus