diff --git a/src/builtins/job_control.rs b/src/builtins/job_control.rs
index cc7c3109cd30d306f00260fa2ed7184c7c0b4a72..b5190a222007ae927d0a6ddc2a4b29b48db86c97 100644
--- a/src/builtins/job_control.rs
+++ b/src/builtins/job_control.rs
@@ -77,7 +77,7 @@ pub fn jobs(shell: &mut Shell) {
     for (id, process) in shell.background.lock().unwrap().iter().enumerate() {
         match process.state {
             ProcessState::Empty => (),
-            _ => { let _ = writeln!(stderr, "[{}] {} {}", id, process.pid, process.state); }
+            _ => { let _ = writeln!(stderr, "[{}] {} {}\t{}", id, process.pid, process.state, process.name); }
         }
     }
 }
diff --git a/src/shell/fork.rs b/src/shell/fork.rs
index 8da1162f9aa8e626d1975cf59ac744bb62e0e53c..5b81545989a31e87afb8da2adc36ca71fb230d08 100644
--- a/src/shell/fork.rs
+++ b/src/shell/fork.rs
@@ -60,11 +60,15 @@ use super::pipe::pipe;
 
 /// Forks the shell, adding the child to the parent's background list, and executing
 /// the given commands in the child fork.
-pub fn fork_pipe(shell: &mut Shell, commands: Vec<(Command, JobKind)>) -> i32 {
+pub fn fork_pipe (
+    shell: &mut Shell,
+    commands: Vec<(Command, JobKind)>,
+    command_name: String
+) -> i32 {
     match ion_fork() {
         Ok(Fork::Parent(pid)) => {
             // The parent process should add the child fork's PID to the background.
-            shell.send_to_background(pid, ProcessState::Running);
+            shell.send_to_background(pid, ProcessState::Running, command_name);
             SUCCESS
         },
         Ok(Fork::Child) => {
diff --git a/src/shell/job_control.rs b/src/shell/job_control.rs
index 806d69e98563505d754e882fef8f98f78fdb104b..e8ea8897c01fb6c9321ddbae5c10da8d9ca35836 100644
--- a/src/shell/job_control.rs
+++ b/src/shell/job_control.rs
@@ -35,8 +35,8 @@ pub trait JobControl {
     fn handle_signal(&self, signal: i32);
     fn foreground_send(&self, signal: i32);
     fn background_send(&self, signal: i32);
-    fn watch_foreground(&mut self, pid: u32) -> i32;
-    fn send_to_background(&mut self, child: u32, state: ProcessState);
+    fn watch_foreground<F: Fn() -> String>(&mut self, pid: u32, get_command: F) -> i32;
+    fn send_to_background(&mut self, child: u32, state: ProcessState, command: String);
 }
 
 #[derive(Clone, Copy, Debug, PartialEq)]
@@ -128,17 +128,28 @@ pub fn watch_background (
 pub fn add_to_background (
     processes: Arc<Mutex<Vec<BackgroundProcess>>>,
     pid: u32,
-    state: ProcessState
+    state: ProcessState,
+    command: String
 ) -> usize {
     let mut processes = processes.lock().unwrap();
     match (*processes).iter().position(|x| x.state == ProcessState::Empty) {
         Some(id) => {
-            (*processes)[id] = BackgroundProcess { pid: pid, ignore_sighup: false, state: state };
+            (*processes)[id] = BackgroundProcess {
+                pid: pid,
+                ignore_sighup: false,
+                state: state,
+                name: command
+            };
             id
         },
         None => {
             let njobs = (*processes).len();
-            (*processes).push(BackgroundProcess { pid: pid, ignore_sighup: false, state: state });
+            (*processes).push(BackgroundProcess {
+                pid: pid,
+                ignore_sighup: false,
+                state: state,
+                name: command
+            });
             njobs
         }
     }
@@ -152,9 +163,8 @@ pub fn add_to_background (
 pub struct BackgroundProcess {
     pub pid: u32,
     pub ignore_sighup: bool,
-    pub state: ProcessState
-    // TODO: Each process should have the command registered to it
-    // pub command: String
+    pub state: ProcessState,
+    pub name: String
 }
 
 impl<'a> JobControl for Shell<'a> {
@@ -207,7 +217,11 @@ impl<'a> JobControl for Shell<'a> {
     }
 
     #[cfg(all(unix, not(target_os = "redox")))]
-    fn watch_foreground(&mut self, pid: u32) -> i32 {
+    fn watch_foreground <F: Fn() -> String> (
+        &mut self,
+        pid: u32,
+        get_command: F
+    ) -> i32 {
         use nix::sys::wait::{waitpid, WaitStatus, WUNTRACED};
         use nix::sys::signal::Signal;
         loop {
@@ -225,7 +239,7 @@ impl<'a> JobControl for Shell<'a> {
                     break TERMINATED;
                 },
                 Ok(WaitStatus::Stopped(pid, _)) => {
-                    self.send_to_background(pid as u32, ProcessState::Stopped);
+                    self.send_to_background(pid as u32, ProcessState::Stopped, get_command());
                     self.received_sigtstp = true;
                     break TERMINATED
                 },
@@ -307,11 +321,11 @@ impl<'a> JobControl for Shell<'a> {
         // TODO: Redox doesn't support signals yet
     }
 
-    fn send_to_background(&mut self, pid: u32, state: ProcessState) {
+    fn send_to_background(&mut self, pid: u32, state: ProcessState, command: String) {
         let processes = self.background.clone();
         let fg_signals = self.foreground_signals.clone();
         let _ = spawn(move || {
-            let njob = add_to_background(processes.clone(), pid, state);
+            let njob = add_to_background(processes.clone(), pid, state, command);
             eprintln!("ion: bg [{}] {}", njob, pid);
             watch_background(fg_signals, processes, pid, njob);
         });
diff --git a/src/shell/pipe.rs b/src/shell/pipe.rs
index 2f31a50a3c105686b20ea081bfa9f525adcfa95c..60483125fe2b0d2ad354ef0d1bac4e1cf151f091 100644
--- a/src/shell/pipe.rs
+++ b/src/shell/pipe.rs
@@ -128,12 +128,25 @@ pub mod crossplat {
     }
 }
 
+// This function serves two purposes:
+// 1. If the result is `Some`, then we will fork the pipeline executing into the background.
+// 2. The value stored within `Some` will be that background job's command name.
+fn check_if_background_job(pipeline: &Pipeline) -> Option<String> {
+    if pipeline.jobs[pipeline.jobs.len()-1].kind == JobKind::Background {
+        Some(pipeline.to_string())
+    } else {
+        None
+    }
+}
+
 pub trait PipelineExecution {
     fn execute_pipeline(&mut self, pipeline: &mut Pipeline) -> i32;
 }
 
 impl<'a> PipelineExecution for Shell<'a> {
     fn execute_pipeline(&mut self, pipeline: &mut Pipeline) -> i32 {
+        let background_string = check_if_background_job(&pipeline);
+
         // Generate a list of commands from the given pipeline
         let mut piped_commands: Vec<(Command, JobKind)> = pipeline.jobs
             .drain(..).map(|mut job| {
@@ -187,8 +200,8 @@ impl<'a> PipelineExecution for Shell<'a> {
 
         self.foreground.clear();
         // If the given pipeline is a background task, fork the shell.
-        if piped_commands[piped_commands.len()-1].1 == JobKind::Background {
-            fork_pipe(self, piped_commands)
+        if let Some(command_name) = background_string {
+            fork_pipe(self, piped_commands, command_name)
         } else {
             // While active, the SIGTTOU signal will be ignored.
             let _sig_ignore = SignalHandler::new();
@@ -320,7 +333,7 @@ fn execute_command(shell: &mut Shell, command: &mut Command, foreground: bool) -
     }).spawn() {
         Ok(child) => {
             if foreground { set_foreground(child.id()); }
-            shell.watch_foreground(child.id())
+            shell.watch_foreground(child.id(), || get_full_command(command))
         },
         Err(_) => {
             let stderr = io::stderr();
@@ -335,16 +348,16 @@ fn execute_command(shell: &mut Shell, command: &mut Command, foreground: bool) -
 fn wait (
     shell: &mut Shell,
     children: &mut Vec<Option<Child>>,
-    commands: Vec<Command>,
+    mut commands: Vec<Command>,
     foreground: bool
 ) -> i32 {
     let end = children.len() - 1;
-    for entry in children.drain(..end).zip(commands.into_iter()) {
-        // _cmd is never used here, but it is important that it gets dropped at the end of this
+    for entry in children.drain(..end).zip(commands.drain(..)) {
+        // It is important that `cmd` gets dropped at the end of this
         // block in order to write EOF to the pipes that it owns.
-        if let (Some(child), _cmd) = entry {
+        if let (Some(child), cmd) = entry {
             if foreground { set_foreground(child.id()); }
-            let status = shell.watch_foreground(child.id());
+            let status = shell.watch_foreground(child.id(), || get_full_command(&cmd));
             if status == TERMINATED {
                 return status
             }
@@ -352,8 +365,9 @@ fn wait (
     }
 
     if let Some(child) = children.pop().unwrap() {
+        let cmd = commands.pop().unwrap();
         if foreground { set_foreground(child.id()); }
-        shell.watch_foreground(child.id())
+        shell.watch_foreground(child.id(), || get_full_command(&cmd))
     } else {
         NO_SUCH_COMMAND
     }
@@ -362,3 +376,15 @@ fn wait (
 fn get_command_name(command: &Command) -> String {
     format!("{:?}", command).split('"').nth(1).unwrap_or("").to_string()
 }
+
+fn get_full_command(command: &Command) -> String {
+    let command = format!("{:?}", command);
+    let mut arg_iter = command.split_whitespace();
+    let command = arg_iter.next().unwrap();
+    let mut output = String::from(&command[1..command.len()-1]);
+    for argument in arg_iter {
+        output.push(' ');
+        output.push_str(&argument[1..argument.len()-1]);
+    }
+    output
+}