diff --git a/src/lib/shell/pipe_exec/mod.rs b/src/lib/shell/pipe_exec/mod.rs
index 898db64f939709dad99aec8fac62e0ad1c7bd4ca..c9594fc863f20dc97545750e6ff7aca929e1f592 100644
--- a/src/lib/shell/pipe_exec/mod.rs
+++ b/src/lib/shell/pipe_exec/mod.rs
@@ -436,7 +436,7 @@ impl PipelineExecution for Shell {
     ) -> i32 {
         let result = sys::fork_and_exec(
             name,
-            &args.iter().map(|s| s.as_ref()).collect::<Vec<_>>(),
+            args,
             if let Some(ref f) = *stdin {
                 Some(f.as_raw_fd())
             } else {
diff --git a/src/lib/sys/redox/mod.rs b/src/lib/sys/redox/mod.rs
index d17176a2f80bee9243a54a92cd4ceb14506ebe0b..cdc1876a66a0dd8fa278396f0868f10f44592a8f 100644
--- a/src/lib/sys/redox/mod.rs
+++ b/src/lib/sys/redox/mod.rs
@@ -83,9 +83,9 @@ pub(crate) fn setpgid(pid: u32, pgid: u32) -> io::Result<()> {
     cvt(syscall::setpgid(pid as usize, pgid as usize)).and(Ok(()))
 }
 
-pub(crate) fn fork_and_exec<F: Fn()>(
+pub(crate) fn fork_and_exec<F: Fn(), S: AsRef<str>>(
     prog: &str,
-    args: &[&str],
+    args: &[S],
     stdin: Option<RawFd>,
     stdout: Option<RawFd>,
     stderr: Option<RawFd>,
@@ -135,12 +135,13 @@ pub(crate) fn fork_and_exec<F: Fn()>(
     }
 }
 
-pub(crate) fn execve(prog: &str, args: &[&str], clear_env: bool) -> io::Error {
+pub(crate) fn execve<S: AsRef<str>>(prog: &str, args: &[S], clear_env: bool) -> io::Error {
     // Construct a valid set of arguments to pass to execve. Ensure
     // that the program is the first argument.
     let mut cvt_args: Vec<[usize; 2]> = Vec::new();
     cvt_args.push([prog.as_ptr() as usize, prog.len()]);
     for arg in args {
+        let arg: &str = arg.as_ref();
         cvt_args.push([arg.as_ptr() as usize, arg.len()]);
     }
 
diff --git a/src/lib/sys/unix/mod.rs b/src/lib/sys/unix/mod.rs
index 38a056432dce3c1a45133229884eda4567c374c7..79109b77e6992cba3bdc076ce9f92f6daf242e0b 100644
--- a/src/lib/sys/unix/mod.rs
+++ b/src/lib/sys/unix/mod.rs
@@ -98,9 +98,9 @@ pub(crate) fn killpg(pgid: u32, signal: i32) -> io::Result<()> {
     cvt(unsafe { libc::kill(-(pgid as pid_t), signal as c_int) }).and(Ok(()))
 }
 
-pub(crate) fn fork_and_exec<F: Fn()>(
+pub(crate) fn fork_and_exec<F: Fn(), S: AsRef<str>>(
     prog: &str,
-    args: &[&str],
+    args: &[S],
     stdin: Option<RawFd>,
     stdout: Option<RawFd>,
     stderr: Option<RawFd>,
@@ -117,8 +117,8 @@ pub(crate) fn fork_and_exec<F: Fn()>(
     // Create a vector of null-terminated strings.
     let mut cvt_args: Vec<CString> = Vec::new();
     cvt_args.push(prog_str.clone());
-    for &arg in args.iter() {
-        match CString::new(arg) {
+    for arg in args.iter() {
+        match CString::new(arg.as_ref()) {
             Ok(arg) => cvt_args.push(arg),
             Err(_) => {
                 return Err(io::Error::last_os_error());
@@ -216,7 +216,7 @@ pub(crate) fn fork_and_exec<F: Fn()>(
     }
 }
 
-pub(crate) fn execve(prog: &str, args: &[String], clear_env: bool) -> io::Error {
+pub(crate) fn execve<'a, S: AsRef<str>>(prog: &str, args: &[S], clear_env: bool) -> io::Error {
     let prog_str = match CString::new(prog) {
         Ok(prog) => prog,
         Err(_) => {
@@ -228,7 +228,7 @@ pub(crate) fn execve(prog: &str, args: &[String], clear_env: bool) -> io::Error
     let mut cvt_args: Vec<CString> = Vec::new();
     cvt_args.push(prog_str.clone());
     for arg in args.iter() {
-        match CString::new(&**arg) {
+        match CString::new(&*arg.as_ref()) {
             Ok(arg) => cvt_args.push(arg),
             Err(_) => {
                 return io::Error::last_os_error();