While the other answers are excellent, I wanted a simple way to compile, cache and run a standalone script. My reasoning being that if I'm distributing a script that depends on rust being installed, I probably can't also depend on some third-party library also being installed in order for it to be compiled.
If I'm going to go to the trouble of passing around multiple files, I might as well just pass around a precompiled binary. If my use case for the script/program is complex enough, then I might as well go through the standard cargo build
process in a git repo.
So for the single file that only depends on rust and the standard library, use a hello.rs
file like the following:
#!/bin/sh
//bin/bash -ec '[ "$0" -nt "${0%.*}" ] && rustc "$0" -o "${0%.*}"; "${0%.*}" "$@"' "$0" "$@"; exit $?
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() > 1 {
println!("Hello {}!", &args[1]);
} else {
println!("Hello world!");
}
}
To help grok what the shebang is doing, try this one instead. It does the same thing, but is easier to maintain:
#!/bin/sh
//bin/bash -exc 'source_file="$0"; exe_file="${source_file%.*}"; [ "$source_file" -nt "$exe_file" ] && rustc "$source_file" -o "$exe_file"; "$exe_file" "$@"' "$0" "$@"; exit $?
This solution is based on the solution by wimh
, but has the following additional features:
- Caches the compiled script, aka the program, in the same directory as the script. This also works when the script's directory is added to the path.
- Passes the script's command line arguments to the program.
- The script's exit code is the same exit code as the program, or the compiler.
Note: the shebang script relies on the script file having some kind of file suffix, e.g. .rs
or .sh
. Without that, the compiler will complain about overwriting the script file with the generated executable.
My testing shows the script adds about 10ms of overhead versus running the compiled program directly.
Edit: There's an RFC in progress to add a solution similar to Scriptisto to the rust core to make a standard way to solve the OP's problem.