Skip to content

Commit 55a6fdb

Browse files
committed
Add std::process::Command::envs()
Command::envs() adds a vector of key-value pairs to the child process environment all at once. Suggested in rust-lang#38526.
1 parent 74e5b7d commit 55a6fdb

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed

src/libstd/process.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,38 @@ impl Command {
377377
self
378378
}
379379

380+
/// Add or update multiple environment variable mappings.
381+
///
382+
/// # Examples
383+
///
384+
/// Basic usage:
385+
/// ```no_run
386+
/// use std::process::{Command, Stdio};
387+
/// use std::env;
388+
///
389+
/// let filtered_env : Vec<(String, String)> =
390+
/// env::vars().filter(|&(ref k, _)|
391+
/// k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
392+
/// ).collect();
393+
///
394+
/// Command::new("printenv")
395+
/// .stdin(Stdio::null())
396+
/// .stdout(Stdio::inherit())
397+
/// .env_clear()
398+
/// .envs(&filtered_env)
399+
/// .spawn()
400+
/// .expect("printenv failed to start");
401+
/// ```
402+
#[stable(feature = "process", since = "1.16.0")]
403+
pub fn envs<K, V>(&mut self, vars: &[(K, V)]) -> &mut Command
404+
where K: AsRef<OsStr>, V: AsRef<OsStr>
405+
{
406+
for &(ref key, ref val) in vars {
407+
self.inner.env(key.as_ref(), val.as_ref());
408+
}
409+
self
410+
}
411+
380412
/// Removes an environment variable mapping.
381413
///
382414
/// # Examples

src/test/run-pass/process-envs.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2014, 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// ignore-emscripten
12+
13+
use std::process::Command;
14+
use std::env;
15+
16+
#[cfg(all(unix, not(target_os="android")))]
17+
pub fn env_cmd() -> Command {
18+
Command::new("env")
19+
}
20+
#[cfg(target_os="android")]
21+
pub fn env_cmd() -> Command {
22+
let mut cmd = Command::new("/system/bin/sh");
23+
cmd.arg("-c").arg("set");
24+
cmd
25+
}
26+
27+
#[cfg(windows)]
28+
pub fn env_cmd() -> Command {
29+
let mut cmd = Command::new("cmd");
30+
cmd.arg("/c").arg("set");
31+
cmd
32+
}
33+
34+
fn main() {
35+
// save original environment
36+
let old_env = env::var_os("RUN_TEST_NEW_ENV");
37+
38+
env::set_var("RUN_TEST_NEW_ENV", "123");
39+
40+
// create filtered environment vector
41+
let filtered_env : Vec<(String, String)> =
42+
env::vars().filter(|&(ref k, _)| k == "PATH").collect();
43+
44+
let mut cmd = env_cmd()
45+
.env_clear()
46+
.envs(&filtered_env);
47+
48+
// restore original environment
49+
match old_env {
50+
None => env::remove_var("RUN_TEST_NEW_ENV"),
51+
Some(val) => env::set_var("RUN_TEST_NEW_ENV", &val)
52+
}
53+
54+
let prog = cmd.spawn().unwrap();
55+
let result = prog.wait_with_output().unwrap();
56+
let output = String::from_utf8_lossy(&result.stdout);
57+
58+
assert!(!output.contains("RUN_TEST_NEW_ENV"),
59+
"found RUN_TEST_NEW_ENV inside of:\n\n{}", output);
60+
}

0 commit comments

Comments
 (0)