Conditional rust command is executed anyway

Playground

Is this a bug?
Because the command does not fail as a shell command.

My issue is that I've got a bunch of commands in a list that I want to run as
part of an installation script.

let my_install_commands = vec![
("Unmounting /mnt/boot..", umount("/mnt/boot"))
...
]

Although I actually want it more like this:

let my_install_commands = vec![
("Unmounting devices..", umount_list(["/mnt/boot", "/mnt/root", ..]))
...
]

Could you try something like this and see if it works?

pub fn umount(path_drive: PathBuf) -> Command {
    let drive = path_drive.to_str().expect(MSG_ERR_PATH_INVALID);
    let mut cmd = Command::new("sh");
    cmd.args(["-c", r#"if [ -d /mnt/boot ]; then sudo umount /mnt/boot; fi"#]);
    cmd
}

Yes, that works.
I guess I'll have to do an sh command for everything then?

If they are single commands (like a single invocation of umount, without the if) then you don't need to spawn a new shell to execute that command

Command deals with executable files, if is a shell builtin command. For this specific problem I'd implement the check in Rust.

5 Likes

It's also always a good idea to make your commands idempotent. In case of umount you could just add the -q flag to suppress errors in case nothing is mounted.

Okay, so it probably would be better for me to give Command::new(true);
when no path is found?

That error is only quiet for mount.

Hmm? If you want to keep the logic inside shell - spawning sh is the way to go. All that /usr/bin/true is exiting with "success" code. My suggestion is about doing a check in rust then spawning or not spawning unmount depending on that.

I'm now thinking of putting my commands inside a Option type.
So I only call them when necessary.

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.