Cmd_lib redirect from string variable

this works:

    let child = spawn!(echo hi > echo.out).unwrap();

but this does not (does nothing so far as i can tell):

    let args = "echo hi > echo.out";
    let child = spawn!($args).unwrap();

nor does this (it prints "hi > echo.out" to stdout):

    let args = shell_words::split("echo hi > echo.out").unwrap();
    let child = spawn!($[args]).unwrap();

is there a way to include redirection in a string that is input into cmd_lib::spawn! ? i need to do so because it is user input.

thanks.

Edit: Sorry, somehow I missed that you already tried the $[args] method...

Something like spawn!(bash -c $args) is one option, though maybe not totally satisfactory.

I believe this is intentional. According to the intuitive parameter passing section of the docs,

You can consider “” as glue, so everything inside the quotes will be treated as a single atomic component.

If they are part of Raw string literals, there will be no string interpolation, the same as in idiomatic rust. However, you can always use format! macro to form the new string. For example:

// string interpolation
let key_word = "time";
let awk_opts = format!(r#"/{}/ {{print $(NF-3) " " $(NF-1) " " $NF}}"#, key_word);
run_cmd!(ping -c 10 www.google.com | awk $awk_opts)?;

Notice here $awk_opts will be treated as single option passing to awk command.

If you want to use dynamic parameters, you can use $[] to access vector variable:

let gopts = vec![vec!["-l", "-a", "/"], vec!["-a", "/var"]];
for opts in gopts {
    run_cmd!(ls $[opts])?;
}

I believe the idea is that the cmd_lib crate just makes it easy to construct a std::process::Command and arguments to it, but it deliberately won't inspect arguments and modify the way commands are executed and connected at runtime. Security is probably not a priority for the library, but doing things this way also automatically "escapes" arguments so you don't open yourself up to shell injection attacks.

If you just want to let the user run arbitrary commands, your best option is to explicitly spawn a shell which executes an arbitrary command (i.e. spawn!(bash -c $args)).

bummer. bash -c is not an option for me as i need a solution that is cross-platform. mac, linux, and windows. and do not want to use WSL.

i already have a bash script that does what i need, and am trying to port to a language which will natively work on windows too. was hoping rust could do that.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.