Команда запуска GLib с привилегиями root

Я пишу очень простое расширение gnome для личного использования (в javascript).

Для запуска консольных команд я использую GLib.spawn_command_line_sync("command");

Оболочка GNOME версии 3.36.2

ЧТО МНЕ НУЖНО

Мне нужно запустить только одну команду, но с привилегиями root, как я могу заставить что-то вроде GLib.spawn_command_line_sync("sudo command"); работать?

Я хотел бы использовать диалоговое окно Authentication Required gnome по умолчанию для ввода пароля.

ЧТО Я ЗНАЮ

Я много читал исходный код и нашел определение диалога, но не понимаю, как его использовать, потому что не могу найти ни одного примера использования.

Я понятия не имею, как связать эти две вещи вместе (диалог и GLib).


person Tommimon    schedule 13.06.2020    source источник


Ответы (1)


Во-первых, избегайте использования GLib.spawn_command_line_sync() в расширениях. Эта функция будет выполняться синхронно в том же потоке, что и анимация и взаимодействие с пользователем, блокируя ее до завершения.

Если вам не нужно выводить статус или выходить из команды, используйте GLib.spawn_command_line_async(). Если вам нужен выход или статус выхода, используйте Gio.Subprocess с communicate_utf8_async().

Чтобы выполнять привилегированные команды от имени пользователя, проще всего использовать pkexec, который будет использовать нужный вам диалог (вы можете проверить это, запустив его в терминале):

// With GLib (no output or success notification)
let cmd = 'apt-get update';

try {
    GLib.spawn_command_line_async('pkexec ' + cmd);
} catch (e) {
    logError(e);
}

// With GSubprocess (output and success notification)
let args = ['apt-get', 'update'];

function privelegedExec(args) {
    try {
        let proc = Gio.Subprocess.new(
            ['pkexec'].concat(args),
            Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE
        );

        proc.communicate_utf8_async(null, null, (proc, res) => {
            try {
                let [, stdout, stderr] = proc.communicate_utf8_finish(res);

                // Failure
                if (!proc.get_successful())
                    throw new Error(stderr);

                // Success
                log(stdout);
            } catch (e) {
                logError(e);
            }
        });
    } catch (e) {
        logError(e);
    }
}   
person andy.holmes    schedule 13.06.2020
comment
Спасатель, работает отлично. Пожалуйста, добавьте закрывающую скобку для privelegedExec(). Я не могу редактировать только один символ. - person Tommimon; 14.06.2020