Open
Description
Problem
std::env::args
and std::env::current_exe
return potentially confusing results when running cargo scripts with the -Zscript
unstable feature. While ostensibly correct, returning the actual built executable path is generally less useful to scripts than returning the path to the cargo script file, and leads to antipatterns like using current_dir().join(SCRIPT_NAME)
to find the script file. Running the executable from the containing directory and having current_dir()
not be a prefix of current_exe()
adds another layer of complexity.
#!/usr/bin/env -S cargo +nightly -Z script
use std::env::{args, current_dir, current_exe};
fn main() {
println!("args: {:?}", args());
println!("current_dir: {}", current_dir().unwrap().display());
println!("current_exe: {}", current_exe().unwrap().display());
}
/tmp/test $ ./test.rs
warning: `package.edition` is unspecified, defaulting to `2021`
Compiling test- v0.0.0 (/tmp/test)
Finished dev [unoptimized + debuginfo] target(s) in 0.13s
Running `/home/rhart/.cargo/target/8c/d68b704094916b/debug/test-`
args: Args { inner: ["/home/rhart/.cargo/target/8c/d68b704094916b/debug/test-"] }
current_dir: /tmp/test
current_exe: /home/rhart/.cargo/target/8c/d68b704094916b/debug/test-
Proposed Solution
It seems there are ~3 possible ways to go about this:
- Leave it as is -- it is correct, despite being a little confusing compared to the typical bash "SCRIPT_DIR" one-liner.
- Override the behavior of these functions somehow to return the path to the script.
std::env::current_exe
has a note that it may return the path of a symbolic link instead of a target of a symbolic link, or other platform specific behavior. Treating the script file as a symbolic link-equivalent whose path is returned instead of the actual executable using this escape hatch is the route I'd personally like best. - Provide a way of accessing the script environment separately from the executable environment.