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

配置sudo运行Cargo测试时执行cargo run报「No such file or directory」错误

问题分析与解决方案

错误原因

当你通过.cargo/config设置runner = 'sudo -E'时,测试进程本身会以sudo权限运行,但测试中执行cargo run时,sudo默认会重置环境变量(即使加了-E,用户目录下的~/.cargo/bin可能不在sudo的PATH里),导致系统找不到cargo命令,抛出NotFound错误。

而不配置sudo runner时,测试进程无特权,子进程调用shmat会因权限不足失败。


解决方案

方案1:给子进程单独加sudo权限(推荐)

无需全局配置sudo runner,直接在测试代码中让子进程以sudo运行,既满足shmat的权限要求,又避免环境变量问题。

修改src/lib.rs的测试代码:

#[cfg(test)]
mod tests {
    #[test]
    fn base() {
        let output = std::process::Command::new("sudo")
            .args(["-E", "cargo", "run", "--bin", "new_process"])
            .output()
            .unwrap();
        dbg!(output);
    }
}

方案2:直接运行编译后的二进制(更高效)

先编译目标二进制,再用sudo运行,避免测试时重复编译:

#[cfg(test)]
mod tests {
    #[test]
    fn base() {
        // 二进制路径根据debug/release环境调整
        let binary_path = "./target/debug/new_process";
        // 先确保二进制已编译
        std::process::Command::new("cargo")
            .args(["build", "--bin", "new_process"])
            .status()
            .unwrap();
        
        let output = std::process::Command::new("sudo")
            .args(["-E", binary_path])
            .output()
            .unwrap();
        dbg!(output);
    }
}

方案3:修复sudo的PATH环境变量(不推荐)

如果你坚持全局配置sudo runner,可修改sudo的环境变量保留原PATH:
修改.cargo/config.toml:

[target.x86_64-unknown-linux-gnu]
runner = 'sudo -E env PATH=$PATH'

这种方法可能带来安全风险,仅在必要时使用。


补充优化:添加错误检查与资源清理

修改src/bin/new_process.rs,添加错误检查并清理共享内存,避免资源泄漏:

fn main() {
    // shmget需指定权限位,否则可能创建失败
    let shmid = libc::shmget(libc::IPC_PRIVATE, 1024*4, libc::IPC_CREAT | 0o666);
    if shmid == -1 {
        eprintln!("shmget 失败: {}", std::io::Error::last_os_error());
        std::process::exit(1);
    }

    let shared_mem_ptr = libc::shmat(shmid, std::ptr::null(), 0);
    if shared_mem_ptr == libc::MAP_FAILED {
        eprintln!("shmat 失败: {}", std::io::Error::last_os_error());
        let _ = libc::shmctl(shmid, libc::IPC_RMID, std::ptr::null_mut());
        std::process::exit(1);
    }

    println!("hello world");

    // 清理共享内存
    if libc::shmctl(shmid, libc::IPC_RMID, std::ptr::null_mut()) == -1 {
        eprintln!("shmctl 失败: {}", std::io::Error::last_os_error());
    }
}

内容的提问来源于stack exchange,提问作者Jonathan Woollett-light

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:39:40