How to pipe commands in rust?
Asked Answered
C

2

11

I am trying to execute a command in a shell and get the return value as a string. The command I'm trying to execute is ps axww | grep mongod | grep -v grep.

I've seen solutions over the internet, but they don't explain the code, so it is hard customising it to my needs.

example: how to do a sandwich pipe in rust? & Pipe between two child processes

Can someone please provide a solution and go line by line explaining how it works in layman's terms.

Ciscaucasia answered 24/8, 2022 at 8:2 Comment(4)
Note: to avoid grep catching it self ps axww | grep [m]ongodUnequivocal
@Unequivocal lol I never though about that, but indeed it was that simple all the time. Thanks for the tip!Entreat
@Unequivocal thanks for the heads up. I got the cmd off the internet... it did seem fishy to me but it worked so... ¯\_(ツ)_/¯Ciscaucasia
Just to explain what that does: grep -v grep will find everything that does not contain grep. Since you look for all process that contain mongod, this will also catch the command you are using to do so (so basically this will prevent showing you the command you are typing).Entreat
E
20

What you need is the documentation, where they do explain everything line by line, with thorough examples. Adapted from it, here is your code

use std::process::{Command, Stdio};
use std::str;

fn main() {
    let ps_child = Command::new("ps") // `ps` command...
        .arg("axww")                  // with argument `axww`...
        .stdout(Stdio::piped())       // of which we will pipe the output.
        .spawn()                      // Once configured, we actually spawn the command...
        .unwrap();                    // and assert everything went right.
    let grep_child_one = Command::new("grep")
        .arg("mongod")
        .stdin(Stdio::from(ps_child.stdout.unwrap())) // Pipe through.
        .stdout(Stdio::piped())
        .spawn()
        .unwrap();
    let grep_child_two = Command::new("grep")
        .arg("-v")
        .arg("grep")
        .stdin(Stdio::from(grep_child_one.stdout.unwrap()))
        .stdout(Stdio::piped())
        .spawn()
        .unwrap();
    let output = grep_child_two.wait_with_output().unwrap();
    let result = str::from_utf8(&output.stdout).unwrap();
    println!("{}", result);
}

See the playground (which of course won't output anything since there is no process called mongod running...).

Entreat answered 24/8, 2022 at 8:29 Comment(0)
F
0

Rust is just splendid language that makes people think creatively. It is not just like C that designed elegantly and carefully so we could just blindly follow.

use std::process::Command;

fn exec(cmd: &str, args: &[&str]) -> String
{
   let output = Command::new(cmd)
   .args(args)
   .output()
   .expect("failed to execute cmd");

   String::from_utf8(output.stdout).unwrap()
}

fn main() {
    let ret = exec("sh", &["-c", "ip addr |grep global"]);
    //let ret = exec("sh", &["-c", "ls -l |grep target"]);
    println!("exec: <{}>", ret);
}
Fionnula answered 18/5, 2023 at 20:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.