0

So I'm making a better command-line frontend for APT and I'm putting on some finishing touches and when the code below runs.

Command::new("unbuffer")
    .arg("apt")
    .arg("list")
    .arg("|")
    .arg("less")
    .arg("-r")
    .status()
    .expect("Something went wrong.");

it spits out:

E: Command line option 'r' [from -r] is not understood in combination with the other options.

but when I just run unbuffer apt list | less -r manually in my terminal it works perfectly. How do I get it to run properly when calling it in Rust?

Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305
SmushyTaco
  • 1,421
  • 2
  • 16
  • 32
  • 4
    `|` is not an argument in bash – Bergi Sep 04 '19 at 01:03
  • @Bergi how do I use `|` then? Also I'm using zsh lol – SmushyTaco Sep 04 '19 at 01:05
  • 1
    Why do you need the pipe (`|`)? The `less` command is usually used for pagination within the terminal. Most likely you want the entire output from the `unbuffer apt list` command to be parsed by Rust, no? If so, leave off the pipe and everything after it. – Matt W Sep 04 '19 at 01:16
  • I'll guess you have to use [the `pipe` crate](https://docs.rs/os_pipe/0.8.1/os_pipe/fn.pipe.html) for that. – Bergi Sep 04 '19 at 01:16
  • 1
    A hack would be to just [send the entire script to a bash command](https://stackoverflow.com/a/38551671/1048572) :-) – Bergi Sep 04 '19 at 01:19
  • 2
    Or maybe it's much easier: https://doc.rust-lang.org/std/process/index.html#handling-io – Bergi Sep 04 '19 at 01:21

1 Answers1

3

Spawning a process via Command uses the system's native functionality to create a process. This is a low level feature and has little to do with your shell/terminal that you are used to. In particular, your shell (e.g. bash or zsh, running inside of your terminal) offers a lot more features. For example, piping via | is such a feature. Command does not support these features as the low level system's API doesn't.

Luckily, the low level interface offers other means of achieving a lot of stuff. Piping for example is mostly just redirecting the standard inputs and outputs. You can do that with Command::{stdin, stdout, sterr}. Please see this part of the documentation for more information.

There are a few very similar questions, which are not similar enough to warrent closing this as a dupe though:

Lukas Kalbertodt
  • 79,749
  • 26
  • 255
  • 305