0

I found std::process in document. But it seems that it cannot work. For example:

fn main() {
    use std::process::Command;

    let command = Command::new("command")
        .arg("-sq")
        .arg("ls")
        .spawn()
        .unwrap();
    println!("{command:#?}");
}

Output:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', 1.rs:8:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

But run the command in shell:

$ command -sq ls && echo true || echo false
true

So how can I get a output like shell in rust?

XXiaoA
  • 51
  • 5
  • `command` is a shell builtin, but `std::process` doesn't use the shell. – kmdreko Sep 08 '22 at 00:58
  • Umm, so are there any way to achieve the same effect? – XXiaoA Sep 08 '22 at 01:09
  • 2
    Achieve what effect? What does `command -sq ls` do? Apparently your shell is different than mine. I could answer how to do the print true/false part, but it wouldn't help solve the error you're seeing. – kmdreko Sep 08 '22 at 01:58
  • `command -sq ls` means find ls's executable file , but be quite (without output). And I'm using fish shell. – XXiaoA Sep 08 '22 at 03:48
  • 1
    I'm guessing this is simply to detect if the program exists? Does this answer your question [Finding executable in PATH with Rust](/q/37498864/2189130) Or if you're going to run it anyway, perhaps this will help [Check if a command is in PATH/executable as process](/q/35045996/2189130) – kmdreko Sep 08 '22 at 04:15
  • 1
    @XXiaoA you can just run the shell itself as executable, with the builtin as your script. – Masklinn Sep 08 '22 at 06:07
  • @kmdreko interestingly `command` checks if a command will work in the shell, it will "hit" on shell builtins and aliases, not just on binaries on the path. – Masklinn Sep 08 '22 at 06:11
  • @Masklinn actually, I not only want to check if the command exists. I hope my script runs after user's shell condition is true. – XXiaoA Sep 08 '22 at 07:48
  • Is `command` a reference to the standard, built-in shell command named `command`, or is it a badly named stand-in for some other command you have but we don't? (Also, **which shell**? On POSIXy ones, `command` doesn't take `-s` or `-q`) – Charles Duffy Sep 08 '22 at 16:48
  • 1
    @XXiaoA, ahh. This really needs to be asked about fish. If you want to use a shell builtin, that's a core part of the question -- include it in title and tagging. (This isn't a Rust problem; to reproduce it in Python, for example, run `import subprocess; subprocess.run(['command', '-sq', 'ls'])` and you'll see a Python version of the same issue). – Charles Duffy Sep 08 '22 at 16:50

1 Answers1

1

The most direct equivalent would be this:

let command = Command::new("fish")
    .args(["-c", "command -sq ls"])
    .output()
    .unwrap();

if command.status.success() {
    println!("true");
} else {
    println!("false");
}

This creates a fish shell which then executes your command command. The .success() method can be used to infer if the command succeeded or failed same as && and || in your script.

kmdreko
  • 42,554
  • 6
  • 57
  • 106
  • Is there a fish equivalent to bash's `bash -c '"$@"'`? If so, you could get access to builtins while still being able to pass an exact argv array. – Charles Duffy Sep 08 '22 at 16:52
  • Fish. Can use `fish -C "command -sq ls". What's more thanks for your help! – XXiaoA Sep 08 '22 at 23:15