配置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
相关产品推荐
相关产品推荐

