Как я могу остановить программу и перезапустить с sudo без ввода пользователем слова sudo? - PullRequest
1 голос
/ 23 сентября 2019
use std::fs::OpenOptions;
use std::io::Write;

fn main() {
    let mut source_list = OpenOptions::new()
        .write(true)
        .append(true)
        .open("/usr/local/etc/apt/sources.list")
        .unwrap();

    if let Err(e) = writeln!(source_list, "{}", "deb ".to_owned() + "https://www.google.com/" + " ./") {
        eprintln!("Couldn't write to file: {}", e);
    }
}

При запуске этого кода без sudo он выдает:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }', src/libcore/result.rs:999:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

, а при запуске этого кода с помощью sudo запрашивает мой пароль, а затем успешно записывает в файл, поэтому мой вопрос: как мне это сделать?заставить его спросить у меня мой пароль, а затем успешно записать в файл без необходимости использования sudo (в основном, как заставить его запускать sudo для пользователя, чтобы он не должен был это делать)?

Ответы [ 2 ]

4 голосов
/ 23 сентября 2019

В основном, как заставить его запускать sudo для пользователя, чтобы ему не приходилось

Вы не можете.

Нормальный способ работы сэта проблема состоит в том, чтобы попытаться, и, в случае сбоя, проанализировать ошибку и вежливо попросить пользователя запустить программу с соответствующими правами:

let source_list = openoptions::new()
        .write(true)
        .append(true)
        .open("/usr/local/etc/apt/sources.list");
match source_list {
    Err(ioerr) => {
        match ioerr.kind() {
            ErrorKind::PermissionDenied => {
                e.println("permission denied. Maybe sudo?");
            }
            _ => {
                e.println("I failed :(");
            }
        }
        return;
    }
    Ok(source_list) => {
        // do things
    }
}
0 голосов
/ 23 сентября 2019

Да, вы можете , но если вы должны , это другой вопрос ...

При обнаружении отсутствия привилегий вы можете перезапустить программу с помощью sudo с помощью std::process::Command и unix - это расширения exec путем выполнения команды с такими же аргументами cmdline.env::args - это итератор для всех аргументов командной строки, где первый - это имя программы

use std::process::Command;
use std::os::unix::process::CommandExt;

 [...]
 // when restart as root is needed
 let cmdlineargs:Vec<String>=env::args().collect();
 let _output = Command::new("sudo")
                    .args(&cmdlineargs)
                    .exec(); // Bye bye never returns

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

Редактировать: Обновлено после предложений в комментариях, замененных spawn на exec

...