在Python中,我可以:
from distutils import spawn
cmd = spawn.find_executable("commandname")
Run Code Online (Sandbox Code Playgroud)
我尝试了类似下面的代码,但它假定您使用的是具有/usr/bin/which
可用的类Unix系统(也涉及到要避免的外部命令的执行):
use std::process::Command;
let output = Command::new("which")
.arg("commandname")
.unwrap_or_else(|e| /* handle error here */)
Run Code Online (Sandbox Code Playgroud)
在Rust中最简单的方法是什么?
我可能会抓住环境变量并对其进行遍历,返回第一个匹配路径:
use std::env;
use std::path::{Path, PathBuf};
fn find_it<P>(exe_name: P) -> Option<PathBuf>
where P: AsRef<Path>,
{
env::var_os("PATH").and_then(|paths| {
env::split_paths(&paths).filter_map(|dir| {
let full_path = dir.join(&exe_name);
if full_path.is_file() {
Some(full_path)
} else {
None
}
}).next()
})
}
fn main() {
println!("{:?}", find_it("cat"));
println!("{:?}", find_it("dog"));
}
Run Code Online (Sandbox Code Playgroud)
在Windows上,这可能很难看,因为您必须将追加.exe
到可执行文件名称上。还应该将其扩展为仅返回可执行的项目,这也是平台特定的代码。
回顾Python实现,看来它们也支持传递绝对路径。函数是否支持该功能取决于您。
快速搜索crates.io返回了一个可能有用的板条箱:quale,尽管它目前说
当前仅在类似Unix的操作系统上工作。
我发现还有其他人也就不足为奇了。
.exe
如果缺少某些丑陋的代码,这些代码会添加到最后,但仅限Windows上。
#[cfg(not(target_os = "windows"))]
fn enhance_exe_name(exe_name: &Path) -> Cow<Path> {
exe_name.into()
}
#[cfg(target_os = "windows")]
fn enhance_exe_name(exe_name: &Path) -> Cow<Path> {
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
let raw_input: Vec<_> = exe_name.as_os_str().encode_wide().collect();
let raw_extension: Vec<_> = OsStr::new(".exe").encode_wide().collect();
if raw_input.ends_with(&raw_extension) {
exe_name.into()
} else {
let mut with_exe = exe_name.as_os_str().to_owned();
with_exe.push(".exe");
PathBuf::from(with_exe).into()
}
}
// At the top of the `find_it` function:
// let exe_name = enhance_exe_name(exe_name.as_ref());
Run Code Online (Sandbox Code Playgroud)