/commands/cargo/cargo-run-with-arguments
cargo run -- args: pass command-line arguments to a Rust program
- tool
- Cargo
- versions
- Cargo 1.x
- os
- any
cargo run -- input.txt --verbose builds the package and runs its binary with input.txt --verbose as arguments. The -- separates Cargo's own options from the program's: everything after it reaches your code through std::env::args() untouched. Plain words without a leading dash also work without -- (cargo run input.txt), but options need it.
Pass arguments
cargo new -q --vcs none args-demo && cd args-demo
cat > src/main.rs <<'EOF'
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
println!("{} argument(s): {:?}", args.len(), args);
}
EOF
cargo run -q -- input.txt --verbose "two words"
cargo run -q
echo "--- without the double dash"
cargo run -q --input data.txt 2>&1 | grep -E "^error|tip:"Output
3 argument(s): ["input.txt", "--verbose", "two words"] 0 argument(s): [] --- without the double dash error: unexpected argument '--input' found tip: to pass '--input' as a value, use '-- --input'
std::env::args() starts with the program path, which the example skips. A quoted value stays one argument. The last command shows the trap: without --, Cargo parses --input as one of its own options, does not know it, and stops before running the program; the tip in the error message gives the fix. An option Cargo does know, such as --verbose or --release, is worse: Cargo silently uses it and the program never sees it.
Variants
| Command | What it does |
|---|---|
| cargo run -- a b | Run the default binary with arguments a and b |
| cargo run --release -- a | Optimised build, then run with argument a |
| cargo run --bin server -- --port 8080 | Pick a binary when the package has several |
| cargo run --example demo -- 42 | Run an example from examples/demo.rs |
| cargo run -p cli -- --help | Run a binary of a workspace member |
| cargo run -q -- a | Hide Cargo status lines, show only program output |
| cargo run --features fast -- a | Enable crate features for this build |
| ./target/debug/args-demo a b | Run the built binary directly, without Cargo |
Pitfalls
- Several binaries. In a package with more than one
[[bin]](or files insrc/bin/),cargo runwithout--binfails and lists the choices, unlessdefault-runis set inCargo.toml. A library-only package fails with a bin target must be available for cargo run. - Working directory. The program runs in the folder where you typed
cargo run, not in the package root, so relative paths in arguments are relative to your shell's current folder. - Exit codes.
cargo runexits with the program's exit code, but a build error also exits non-zero. In scripts, build first withcargo buildand then run the binary to tell the two apart. - Non-UTF-8 arguments.
std::env::args()panics on arguments that are not valid Unicode; usestd::env::args_os()when you accept arbitrary file names.
How to confirm it worked
Print the arguments as in the example, or run the program with --help if it uses an argument parser such as clap: cargo run -- --help shows the program's help, while cargo run --help shows Cargo's.
FAQ
Why does cargo say unexpected argument when I pass --verbose to my program?
Without the double dash, Cargo reads --verbose (and any other option) as its own option, and an unknown one fails with unexpected argument. Put the program's arguments after --, for example cargo run -- --verbose input.txt.
How do I run a release build with arguments?
Put --release before the double dash: cargo run --release -- input.txt. Everything before -- configures Cargo, everything after it is passed to the program.
How do I pass arguments to an example or another binary?
Select the target first, then the arguments: cargo run --example demo -- 42, or cargo run --bin server -- --port 8080.