You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过rpassword或Polkit实现无交互sudo命令执行?

过时的初始方案

我尝试通过sudo启动命令,并借助rpassword的BufRead实现向进程传递密码。

为避免在TTY上弹出密码提示,我使用了sudo的-S参数。启动命令时,我通过take()获取stdin,再启动一个线程将通过BufRead保存的密码写入stdin,这是按照Rust官方文档的建议操作的。

示例代码如下:

use rpassword::read_password_from_bufread;
use std::{
    io::{Cursor, Write},
    process::{Command, Stdio},
    thread,
};

fn sudo_cmd(pw: String) {
    let mut cmd = Command::new("sudo")
        .arg("-S")
        .arg("ls")
        .stdin(Stdio::piped())
        .stdout(Stdio::piped())
        // .stderr(Stdio::null()) //<<== should hide password prompt
        .spawn()
        .ok()
        .expect("not spawned");

    let mut stdin = cmd.stdin.take().expect("Couldnt take stdin");

    thread::spawn(move || {
        stdin
            .write_all(pw.as_bytes())
            .expect("Couldnt write stding");
    });

    let output = cmd.wait_with_output().expect("wheres the output");

    println!(
        "Output:\n{}",
        String::from_utf8(output.stdout).expect("Cant read stdout")
    );
}

fn main() {
    let mut mock_input = Cursor::new("my-password\n".as_bytes().to_owned());
    let password = read_password_from_bufread(&mut mock_input).unwrap();
    sudo_cmd(password);
}

遗憾的是,该方案无法正常工作。进程等待片刻后退出,仿佛未提供密码一般:

Compiling testproject v0.1.0 (/home/lukeflo/Documents/projects/coding/testfiles/rust-tests/testproject)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
     Running `target/debug/testproject`
Password: Sorry, try again.
Password: 
sudo: no password was provided
sudo: 1 incorrect password attempt
Output:

暂不考虑安全问题,正确的实现方式是什么?我无法/不愿直接使用TTY提示(纯CLI应用可以做到),因为我想了解如何像密码管理器的GUI包装器那样“间接”收集密码。

编辑:使用Polkit

对于GUI/TUI应用,Polkit似乎是合适的方案。但据我所知,用于Polkit交互的Rust库很少,且文档不完善,或许我有所遗漏。希望能获得相关建议,整体代码结构保持不变,我只想通过Polkit完成sudo命令的认证。


内容的提问来源于stack exchange,提问作者lukeflo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 06:55:00