1

I am trying to execute a sequence of commands in the same process. E.g.

let v = vec!["python3 -m venv venv", "source venv/bin/activate"];

I have tried joining the vector with " && " and using the .args method to no avail. I.e.

std::process::Command::new("python3")
    .args(&["-m", "venv", "venv", "&&", "source", "venv/bin/activate"])
    .output()
    .expect("failed to execute command");

What is the best way to do this?

Note: I want to do this all in the same process to use the Python virtual env that is activated.

Alex
  • 18,484
  • 8
  • 60
  • 80
  • 3
    If you want to use shell syntax you need to invoke a shell. – CodesInChaos May 30 '18 at 20:35
  • @CodesInChaos doh! If you write up an answer I'll accept it... Otherwise will self-answer and leave this up for reference. – Alex May 30 '18 at 20:41
  • There is probably a better solution not involving a shell. And "in the same process" looks wrong to me, but I'll leave that to somebody with better unix knowledge than me. – CodesInChaos May 30 '18 at 20:44
  • It would be better to mark this as a duplicate of an existing question (if one exists). I found [Execute any bash command, get the results of stdout/stderr immediatly and use stdin](https://stackoverflow.com/questions/38551500/execute-any-bash-command-get-the-results-of-stdout-stderr-immediatly-and-use-st) and [Execute a shell command](https://stackoverflow.com/questions/31666936/execute-a-shell-command) that look like candidates. (One answer to the second one suggests using `Result::and_then` in Rust to emulate `&&` in the shell, which strikes me as the best idea.) – trent May 30 '18 at 20:48
  • @trentcl good finds - voting to close this as dupe... It strikes me that the `Result::and_then` call would occur after the process has exited. – Alex May 30 '18 at 21:01
  • 1
    Yes, that's what a shell would do, too. I don't know if "reusing" the subprocess is really a thing that you *can* do. Isn't it gone when the first command terminates? – trent May 30 '18 at 21:06
  • @trentcl AFAIK that is correct. – Alex May 30 '18 at 21:08
  • Note that all that `activate` does is to set an environment variables (`VIRTUAL_ENV`), prepend `$VIRTUAL_ENV/bin` to the `PATH` and unset `PYTHON_HOME`, which you can do yourself before calling your main command (I'd post an answer, except that the question is closed…) – Jmb May 31 '18 at 06:34
  • @Jmb Yeah but that doesn't help with this problem... manually setting the environment variables would still need to be done in the same process (before the other commands are executed). – Alex Jun 01 '18 at 16:11
  • 1
    @Alex This can be done with [Command::env](https://doc.rust-lang.org/stable/std/process/struct.Command.html#method.env) for a single command or with [std::env](https://doc.rust-lang.org/stable/std/env/index.html) for the current process (and therefore for all its future children). – Jmb Jun 04 '18 at 06:33

0 Answers0