3

私の現在の gksudo コマンドは、Process.spawn_async_with_pipes で動作します。ただし、gksudo を pkexec に切り替えると、pkexec ウィンドウが表示されず、プロンプトなしでコマンドが直接完了し、何も返されません。

同じ pkexec コマンドで Process.spawn_command_line_sync を使用すると、パスワードを要求するプロンプトが表示され、コマンドが正常に実行され、結果が返されます。

私が pkexec を使用する主な理由は、polkit を使用し、root 権限を必要とするコマンドのその後の使用についてユーザーにプロンプ​​トを表示しないことです。

Process.spawn_async_with_pipes コードの私の方法を以下に示します。

pkexec をバックグラウンド プロセスとして動作させる方法について助けが必要です。つまり、プロンプトは GUI をブロックする必要がありますが、ユーザーがパスワードを入力すると、制御を GUI に戻し、バックグラウンドで実行を継続する必要があります。これはまさに gksudo で起こることです。

前もって感謝します

これは非同期メソッドです

public int execute_sync_multiarg_command_pipes(string[] spawn_args) {
        debug("Starting to execute async command: "+string.joinv(" ", spawn_args));
        spawn_async_with_pipes_output.erase(0, -1); //clear the output buffer
        MainLoop loop = new MainLoop ();
        try {
            string[] spawn_env = Environ.get();
            Pid child_pid;

            int standard_input;
            int standard_output;
            int standard_error;

            Process.spawn_async_with_pipes ("/",
                spawn_args,
                spawn_env,
                SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD,
                null,
                out child_pid,
                out standard_input,
                out standard_output,
                out standard_error);

            // capture stdout:
            IOChannel output = new IOChannel.unix_new (standard_output);
            output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => {
                return process_line (channel, condition, "stdout");
            });

            // capture stderr:
            IOChannel error = new IOChannel.unix_new (standard_error);
            error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => {
                return process_line (channel, condition, "stderr");
            });

            ChildWatch.add (child_pid, (pid, status) => {
                // Triggered when the child indicated by child_pid exits
                Process.close_pid (pid);
                loop.quit ();
            });
            loop.run ();
        } catch(SpawnError e) {
            warning("Failure in executing async command ["+string.joinv(" ", spawn_args)+"] : "+e.message);
            spawn_async_with_pipes_output.append(e.message);
        }
        debug("Completed executing async command["+string.joinv(" ", spawn_args)+"]...");
        return 0;
    }`

これは、それがどのように呼び出されているかです:

execute_sync_multiarg_command_pipes({"pkexec", COMMAND_USING_SUDO[6]});
4

1 に答える 1

0

非同期 pkexec コマンドの生成は次のように機能します。

public static int main (string[] args) {
    MainLoop loop = new MainLoop ();
    try {
        string[] spawn_args = {"pkexec", "ls", "-l", "-h"};
        string[] spawn_env = Environ.get ();
        Pid child_pid;

        Process.spawn_async ("/",
            spawn_args,
            spawn_env,
            SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD,
            null,
            out child_pid);

        ChildWatch.add (child_pid, (pid, status) => {
            // Triggered when the child indicated by child_pid exits
            Process.close_pid (pid);
            loop.quit ();
        });

        loop.run ();
    } catch (SpawnError e) {
        stdout.printf ("Error: %s\n", e.message);
    }
    return 0;
}

プロンプトが表示され、結果のファイル リストは、予想どおり「/root」ディレクトリからのものです。

したがって、問題は別の場所にあるはずです。

パイプでも動作します:

private static bool process_line (IOChannel channel, IOCondition condition, string stream_name) {
    if (condition == IOCondition.HUP) {
        stdout.printf ("%s: The fd has been closed.\n", stream_name);
        return false;
    }

    try {
        string line;
        channel.read_line (out line, null, null);
        stdout.printf ("%s: %s", stream_name, line);
    } catch (IOChannelError e) {
        stdout.printf ("%s: IOChannelError: %s\n", stream_name, e.message);
        return false;
    } catch (ConvertError e) {
        stdout.printf ("%s: ConvertError: %s\n", stream_name, e.message);
        return false;
    }

    return true;
}

public static int main (string[] args) {
    MainLoop loop = new MainLoop ();
    try {
        string[] spawn_args = {"pkexec", "ls", "-l", "-h"};
        string[] spawn_env = Environ.get ();
        Pid child_pid;

        int standard_input;
        int standard_output;
        int standard_error;

        Process.spawn_async_with_pipes ("/",
            spawn_args,
            spawn_env,
            SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD,
            null,
            out child_pid,
            out standard_input,
            out standard_output,
            out standard_error);

        // stdout:
        IOChannel output = new IOChannel.unix_new (standard_output);
        output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => {
            return process_line (channel, condition, "stdout");
        });

        // stderr:
        IOChannel error = new IOChannel.unix_new (standard_error);
        error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => {
            return process_line (channel, condition, "stderr");
        });

        ChildWatch.add (child_pid, (pid, status) => {
            // Triggered when the child indicated by child_pid exits
            Process.close_pid (pid);
            loop.quit ();
        });

        loop.run ();
    } catch (SpawnError e) {
        stdout.printf ("Error: %s\n", e.message);
    }
    return 0;
}

これでも(サンプルコードフラグメントが含まれています)動作します:

StringBuilder spawn_async_with_pipes_output;

private static bool process_line (IOChannel channel, IOCondition condition, string stream_name) {
    if (condition == IOCondition.HUP) {
        stdout.printf ("%s: The fd has been closed.\n", stream_name);
        return false;
    }

    try {
        string line;
        channel.read_line (out line, null, null);
        stdout.printf ("%s: %s", stream_name, line);
    } catch (IOChannelError e) {
        stdout.printf ("%s: IOChannelError: %s\n", stream_name, e.message);
        return false;
    } catch (ConvertError e) {
        stdout.printf ("%s: ConvertError: %s\n", stream_name, e.message);
        return false;
    }

    return true;
}

public int execute_sync_multiarg_command_pipes(string[] spawn_args) {
        debug("Starting to execute async command: "+string.joinv(" ", spawn_args));
        spawn_async_with_pipes_output.erase(0, -1); //clear the output buffer
        MainLoop loop = new MainLoop ();
        try {
            string[] spawn_env = Environ.get();
            Pid child_pid;

            int standard_input;
            int standard_output;
            int standard_error;

            Process.spawn_async_with_pipes ("/",
                spawn_args,
                spawn_env,
                SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD,
                null,
                out child_pid,
                out standard_input,
                out standard_output,
                out standard_error);

            // capture stdout:
            IOChannel output = new IOChannel.unix_new (standard_output);
            output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => {
                return process_line (channel, condition, "stdout");
            });

            // capture stderr:
            IOChannel error = new IOChannel.unix_new (standard_error);
            error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => {
                return process_line (channel, condition, "stderr");
            });

            ChildWatch.add (child_pid, (pid, status) => {
                // Triggered when the child indicated by child_pid exits
                Process.close_pid (pid);
                loop.quit ();
            });
            loop.run ();
        } catch(SpawnError e) {
            warning("Failure in executing async command ["+string.joinv(" ", spawn_args)+"] : "+e.message);
            spawn_async_with_pipes_output.append(e.message);
        }
        debug("Completed executing async command["+string.joinv(" ", spawn_args)+"]...");
        return 0;
    }

public static int main (string[] args) {
    spawn_async_with_pipes_output = new StringBuilder ();
    execute_sync_multiarg_command_pipes ({"pkexec", "ls", "-l", "-h"});
    return 0;
}
于 2016-10-17T08:00:42.753 に答える