Command::new
is indeed the way to go, but it is meant to execute a program. ls ; sleep 1; ls
is not a program, it's instructions for some shell. If you want to execute something like that, you would need to ask a shell to interpret that for you:
Command::new("/usr/bin/sh").args(&["-c", "ls ; sleep 1; ls"])
// your complex command is just an argument for the shell
To get the output, there are two ways:
- the
output
method is blocking and returns the outputs and the exit status of the command.
- the
spawn
method is non-blocking, and returns a handle containing the child's process stdin
, stdout
and stderr
so you can communicate with the child, and a wait
method to wait for it to cleanly exit. Note that by default the child inherits its parent file descriptor and you might want to set up pipes instead:
You should use something like:
let child = Command::new("/usr/bin/sh")
.args(&["-c", "ls sleep 1 ls"])
.stderr(std::process::Stdio::null()) // don't care about stderr
.stdout(std::process::Stdio::piped()) // set up stdout so we can read it
.stdin(std::process::Stdio::piped()) // set up stdin so we can write on it
.spawn().expect("Could not run the command"); // finally run the command
write_something_on(child.stdin);
read(child.stdout);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…