rust-shell-script / rust_cmd_lib

Common rust command-line macros and utilities, to write shell-script like tasks in a clean, natural and rusty way
https://docs.rs/cmd_lib/
Apache License 2.0
1.05k stars 37 forks source link

how to use vector of arguments in run_cmd? #42

Closed horacimacias closed 2 years ago

horacimacias commented 2 years ago

this is more a question than an issue, but I'm trying to do something like:

run_cmd!(docker save $all_images -o images.tar)

where all_images is a Vec<String>.

I tried converting the vector to a single String, let all_images = all_images.join(" "); but the command is ran with docker save "image1 image2 image3" -o images.tar which makes docker think I'm saving only one image when in fact is multiple. Using the Vector directly does not compile due to some trait bounds not being satisfied which I think I kind of understand but don't see how to overcome.

Any suggestions?

horacimacias commented 2 years ago

I've also tried run_cmd!(docker save $[all_images] -o images.tar) but I'm getting a vector variable can only be used alone.

Even the example on the readme:

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

doesn't seem to compile for me? 🤷

horacimacias commented 2 years ago

in case this is of any help, I ended up using:

    let docker_save: Vec<_> = vec!["docker", "save", "-o", "images.tar"]
        .into_iter()
        .map(ToOwned::to_owned)
        .chain(all_images.into_iter())
        .collect();
    run_cmd!($[docker_save])?;

but I'd love to see a better way. Also I'm still not getting why the ls $[opts] example doesn't compile?

rust-shell-script commented 2 years ago

Here is from my machine:

➜  rust_cmd_lib git:(master) ✗ cat examples/test.rs 
use cmd_lib::*;

fn main() -> CmdResult {
    cmd_lib::set_debug(true);
    init_builtin_logger();

    let gopts = vec![vec!["-l", "-a", "/"], vec!["-a", "/var"]];
    for opts in gopts {
        run_cmd!(ls $[opts])?;
    }
    Ok(())
}
➜  rust_cmd_lib git:(master) ✗ cargo run --example test
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/examples/test`
DEBUG - Running ["ls", "-l", "-a", "/"] ...
total 116
drwxr-xr-x  24 root root  4096 Jul 29 21:03 .
drwxr-xr-x  24 root root  4096 Jul 29 21:03 ..
drwxr-xr-x   2 root root  4096 Apr 23  2021 bin
drwxr-xr-x   4 root root  4096 Jul 29 21:04 boot
drwxr-xr-x   2 root root  4096 Dec 29  2020 cdrom
drwxr-xr-x  20 root root  4220 Dec 19 21:34 dev
drwxr-xr-x 145 root root 12288 Dec  1 23:31 etc
drwxr-xr-x   6 root root  4096 Jun 20  2021 home
lrwxrwxrwx   1 root root    34 Jul 29 21:03 initrd.img -> boot/initrd.img-4.15.0-140-generic
lrwxrwxrwx   1 root root    34 Jul 29 21:03 initrd.img.old -> boot/initrd.img-4.15.0-142-generic
drwxr-xr-x  22 root root  4096 Jun 20  2021 lib
drwxr-xr-x   2 root root  4096 May 15  2021 lib64
drwx------   2 root root 16384 Dec 29  2020 lost+found
drwxr-xr-x   3 root root  4096 Dec 29  2020 media
drwxr-xr-x   2 root root  4096 Aug  6  2020 mnt
drwxr-xr-x   4 root root  4096 Aug 15 14:32 opt
dr-xr-xr-x 261 root root     0 Nov 21 19:43 proc
drwx------   5 root root  4096 Jun 19  2021 root
drwxr-xr-x  27 root root   900 Dec 20 23:30 run
drwxr-xr-x   2 root root 12288 May 15  2021 sbin
drwxr-xr-x   2 root root  4096 Dec 29  2020 snap
drwxr-xr-x   2 root root  4096 Aug  6  2020 srv
dr-xr-xr-x  13 root root     0 Dec 20 23:45 sys
drwxrwxrwt  40 root root 12288 Dec 20 23:48 tmp
drwxr-xr-x  13 root root  4096 Jun 20  2021 usr
drwxr-xr-x  14 root root  4096 Aug  6  2020 var
lrwxrwxrwx   1 root root    31 Jul 29 21:03 vmlinuz -> boot/vmlinuz-4.15.0-140-generic
lrwxrwxrwx   1 root root    31 Jul 29 21:03 vmlinuz.old -> boot/vmlinuz-4.15.0-142-generic
DEBUG - Running ["ls", "-a", "/var"] ...
.  ..  backups  cache  crash  lib  local  lock  log  mail  metrics  opt  run  snap  spool  tmp

You can also run cargo expand to get more details.

rust-shell-script commented 2 years ago

It works for me:

➜  rust_cmd_lib git:(master) ✗ cat examples/test2.rs
use cmd_lib::*;

fn main() -> CmdResult {
    cmd_lib::set_debug(true);
    init_builtin_logger();

    let images = vec!["image1", "image2", "image3"];
    run_cmd!(docker save $[images] -o images.tar)?;
    Ok(())
}
➜  rust_cmd_lib git:(master) ✗ cargo run --example test2
   Compiling cmd_lib v1.3.0 (/home/tao/src/rust/rust_cmd_lib)
    Finished dev [unoptimized + debuginfo] target(s) in 0.47s
     Running `target/debug/examples/test2`
DEBUG - Running ["docker", "save", "image1", "image2", "image3", "-o", "images.tar"] ...
Error: Os { code: 2, kind: NotFound, message: "No such file or directory" }
horacimacias commented 2 years ago

thanks for checking this and sorry as it may have been me overlooking this.

vscode is still complaining for me:

image

BUT clippy is absolutely fine and I can run the program successfully, so the problem is on my side.

sorry again and thanks for cmd_lib; I was looking for something to avoid using shell scripts once they get too complex and this is making things much nicer for me 👏 👏