# Allow std::process::Command to change args

**URL:** <https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601>\
**Category:** libs\
**Created:** [May 10, 2022, 7:02pm UTC](https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601 "2022-05-10T19:02:05Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zooce](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zooce/32/9374_2.png) [@Zooce](https://internals.rust-lang.org/u/Zooce)\
**Post date:** [May 10, 2022, 7:02pm UTC](https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601/1 "2022-05-10T19:02:05Z")

</div>

I think the basic, common usage of `std::process::Command` looks something like this:

```rust
Command::new("git")
    .current_dir("/home/zooce/project")
    .args(["fetch", "-a"])
    .output()?;

```

But what if you wanted to use the same program (and probably current directory) for several steps? You have to create new commands for every step like this:

```rust
Command::new("git")
    .current_dir("/home/zooce/project")
    .args(["fetch", "-a"])
    .output()?;
Command::new("git")
    .current_dir("/home/zooce/project")
    .arg("pull")
    .output()?;
Command::new("git")
    .current_dir("/home/zooce/project")
    .args(["submodule", "udpate", "--init", "--recursive"])
    .output()?;

```

In this case it would be nice if `Command` allowed us to change its arguments but keep the program like this:

```rust
let mut git = Command::new("git");
git.current_dir("/home/zooce/project");

// just using `set_args` to differentiate from `args`
git.set_args(["fetch", "-a"]).output()?;
git.set_args(["pull"]).output()?;
git.set_args(["submodule", "udpate", "--init", "--recursive"]).output()?;

```

This might be kind of a dumb example, but I think it gets the point across.

Curious on others' thoughts about this...

---

<div class="post-metadata">

**Author:** ![Zooce](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zooce/32/9374_2.png) [@Zooce](https://internals.rust-lang.org/u/Zooce)\
**Post date:** [May 10, 2022, 9:18pm UTC](https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601/2 "2022-05-10T21:18:16Z")

</div>

I also want to note that `std::process::Command` already has a way to achieve this for environment variables with [`clear_env()`](https://doc.rust-lang.org/stable/std/process/struct.Command.html#method.env_clear) so you can have a new set of environment variables but use the same instance of `Command`. So another possibility is to add a `clear_args()` function:

```rust
let mut git = Command::new("git");
git.current_dir("/home/zooce/project");

git.args(["fetch", "-a"]).output()?;
git.clear_args().arg("pull").output()?;
git.clear_args().args(["submodule", "update", "--init", "--recursive"]).output()?;

```

---

<div class="post-metadata">

**Author:** ![ehuss](https://avatars.discourse-cdn.com/v4/letter/e/9de0a6/32.png) [@ehuss](https://internals.rust-lang.org/u/ehuss)\
**Post date:** [May 10, 2022, 9:51pm UTC](https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601/3 "2022-05-10T21:51:52Z")

</div>

There is already a proposal to add mutation methods at [Mutate command args by cehteh · Pull Request #87420 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/pull/87420).

---

<div class="post-metadata">

**Author:** ![Zooce](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zooce/32/9374_2.png) [@Zooce](https://internals.rust-lang.org/u/Zooce)\
**Post date:** [May 10, 2022, 10:18pm UTC](https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601/4 "2022-05-10T22:18:55Z")

</div>

Yep, see that now! Thank you!!

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [May 11, 2022, 1:55am UTC](https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601/5 "2022-05-11T01:55:59Z")

</div>

A pattern that helps in cases like this is to use a small helper closure:

```rust
let git = || Command::new("git")
    .current_dir("/home/zooce/project");

git()
    .args(["fetch", "-a"])
    .output()?;
git()
    .arg("pull")
    .output()?;
git()
    .args(["submodule", "udpate", "--init", "--recursive"])
    .output()?;

```

---

<div class="post-metadata">

**Author:** ![Zooce](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zooce/32/9374_2.png) [@Zooce](https://internals.rust-lang.org/u/Zooce)\
**Post date:** [May 11, 2022, 3:09am UTC](https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601/6 "2022-05-11T03:09:20Z")

</div>

Nice! That's pretty clever. That will help me in the meantime - thank you!!

---

<div class="post-metadata">

**Author:** ![Zooce](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zooce/32/9374_2.png) [@Zooce](https://internals.rust-lang.org/u/Zooce)\
**Post date:** [May 11, 2022, 4:49pm UTC](https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601/7 "2022-05-11T16:49:22Z")

</div>

So I realized that the following doesn't work because `current_dir()` would return a reference to a temporary value (because it's in a closure).

```rust
let git = || Command::new("git").current_dir("/home/zooce/project");

```

So I'm doing this instead:

```rust
let git = |args: &[&str]| Command::new("git")
    .current_dir("/home/zooce/project")
    .args(args)
    .output();

git(&["fetch", "-a"])?;
git(&["pull"])?;
git(&["submodule", "update", "--init", "--recursive"])?;

```

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [August 9, 2022, 4:49pm UTC](https://internals.rust-lang.org/t/allow-std-command-to-change-args/16601/8 "2022-08-09T16:49:26Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
