diff --git a/src/parser/shell_expand/words.rs b/src/parser/shell_expand/words.rs
index f9b254d2d90de02d8d1ee45b0d6765b54b04a893..fb65a1ef5aec0054a2d79924d18c0b4838ecad89 100644
--- a/src/parser/shell_expand/words.rs
+++ b/src/parser/shell_expand/words.rs
@@ -1277,11 +1277,13 @@ impl<'a, E: Expander + 'a> Iterator for WordIterator<'a, E> {
                         self.read += 1;
                         return Some(self.braces(&mut iterator));
                     }
-                    b'[' if !self.flags.intersects(SQUOTE | DQUOTE) => if self.glob_check(&mut iterator) {
-                        glob = true;
-                    } else {
-                        return Some(self.array(&mut iterator));
-                    },
+                    b'[' if !self.flags.intersects(SQUOTE | DQUOTE) => {
+                        if self.glob_check(&mut iterator) {
+                            glob = true;
+                        } else {
+                            return Some(self.array(&mut iterator));
+                        }
+                    }
                     b'@' if !self.flags.contains(SQUOTE) => match iterator.next() {
                         Some(b'(') => {
                             self.read += 2;
@@ -1397,11 +1399,13 @@ impl<'a, E: Expander + 'a> Iterator for WordIterator<'a, E> {
                         return self.next();
                     };
                 }
-                b'[' if !self.flags.intersects(SQUOTE | DQUOTE) => if self.glob_check(&mut iterator) {
-                    glob = true;
-                } else {
-                    return Some(WordToken::Normal(&self.data[start..self.read], glob, tilde));
-                },
+                b'[' if !self.flags.intersects(SQUOTE | DQUOTE) => {
+                    if self.glob_check(&mut iterator) {
+                        glob = true;
+                    } else {
+                        return Some(WordToken::Normal(&self.data[start..self.read], glob, tilde));
+                    }
+                }
                 b'*' | b'?' if !self.flags.contains(SQUOTE) => {
                     glob = true;
                 }
diff --git a/src/shell/binary.rs b/src/shell/binary.rs
index 45e0be208e32d791778bc0a230f3c4caf20b07b1..f2e43c1bf27f077e4c38f64a11adc3ffabb5c8fc 100644
--- a/src/shell/binary.rs
+++ b/src/shell/binary.rs
@@ -1,7 +1,7 @@
 //! Contains the binary logic of Ion.
-
 use super::{DirectoryStack, FlowLogic, JobControl, Shell, ShellHistory, Variables};
 use super::completer::*;
+use super::flags::*;
 use super::flow_control::Statement;
 use super::library::IonLibrary;
 use super::status::*;
@@ -31,7 +31,7 @@ pub(crate) trait Binary {
     /// Creates an interactive session that reads from a prompt provided by Liner.
     fn execute_interactive(self);
     /// Ensures that read statements from a script are terminated.
-    fn terminate_script_quotes<I: Iterator<Item = String>>(&mut self, lines: I);
+    fn terminate_script_quotes<I: Iterator<Item = String>>(&mut self, lines: I) -> i32;
     /// Ensures that read statements from the interactive prompt is terminated.
     fn terminate_quotes(&mut self, command: String) -> Result<String, ()>;
     /// Ion's interface to Liner's `read_line` method, which handles everything related to
@@ -214,7 +214,7 @@ impl<'a> Binary for Shell<'a> {
         self.exit(previous_status);
     }
 
-    fn terminate_script_quotes<I: Iterator<Item = String>>(&mut self, mut lines: I) {
+    fn terminate_script_quotes<I: Iterator<Item = String>>(&mut self, mut lines: I) -> i32 {
         while let Some(command) = lines.next() {
             let mut buffer = QuoteTerminator::new(command);
             while !buffer.check_termination() {
@@ -225,12 +225,13 @@ impl<'a> Binary for Shell<'a> {
                     } else {
                         let stderr = io::stderr();
                         let _ = writeln!(stderr.lock(), "ion: unterminated quote in script");
-                        self.exit(FAILURE);
+                        return FAILURE;
                     }
                 }
             }
             self.on_command(&buffer.consume());
         }
+
         // The flow control level being non zero means that we have a statement that has
         // only been partially parsed.
         if self.flow_control.level != 0 {
@@ -238,7 +239,10 @@ impl<'a> Binary for Shell<'a> {
                 "ion: unexpected end of script: expected end block for `{}`",
                 self.flow_control.current_statement.short()
             );
+            return FAILURE;
         }
+
+        SUCCESS
     }
 
     fn terminate_quotes(&mut self, command: String) -> Result<String, ()> {
@@ -275,6 +279,14 @@ impl<'a> Binary for Shell<'a> {
             let _ = writeln!(stderr, "ion: -c requires an argument");
             self.exit(FAILURE);
         }
+
+        if self.flow_control.level != 0 {
+            eprintln!(
+                "ion: unexpected end of arguments: expected end block for `{}`",
+                self.flow_control.current_statement.short()
+            );
+            self.exit(FAILURE);
+        }
     }
 
     fn execute_interactive(mut self) {
@@ -319,11 +331,11 @@ impl<'a> Binary for Shell<'a> {
                         match self.variables.tilde_expansion(cmd, &self.directory_stack) {
                             Some(ref cmd) if Path::new(cmd).is_dir() & !cmd.ends_with('/') => {
                                 self.save_command_in_history(&[cmd, "/"].concat());
-                            },
+                            }
                             None if Path::new(cmd).is_dir() & !cmd.ends_with('/') => {
                                 self.save_command_in_history(&[cmd, "/"].concat());
                             }
-                            _ => self.save_command_in_history(cmd)
+                            _ => self.save_command_in_history(cmd),
                         }
                     } else {
                         self.flow_control.level = 0;
@@ -342,8 +354,12 @@ impl<'a> Binary for Shell<'a> {
 
     fn main(mut self) {
         let mut args = env::args().skip(1);
-        if let Some(path) = args.next() {
+        while let Some(path) = args.next() {
             match path.as_str() {
+                "-n" => {
+                    self.flags |= NO_EXEC;
+                    continue;
+                }
                 "-c" => self.execute_arguments(args),
                 "--version" => self.display_version(),
                 _ => {
@@ -361,9 +377,9 @@ impl<'a> Binary for Shell<'a> {
             self.wait_for_background();
             let previous_status = self.previous_status;
             self.exit(previous_status);
-        } else {
-            self.execute_interactive();
         }
+
+        self.execute_interactive();
     }
 
     fn display_version(&self) {
diff --git a/src/shell/flags.rs b/src/shell/flags.rs
index e2a72ceddd7467196e31585f7ce78a6c31e93d34..b5de908e8864b32e30c4d599dd90b5e797e127d5 100644
--- a/src/shell/flags.rs
+++ b/src/shell/flags.rs
@@ -1,2 +1,3 @@
 pub const ERR_EXIT: u8 = 1;
 pub const PRINT_COMMS: u8 = 2;
+pub const NO_EXEC: u8 = 4;
diff --git a/src/shell/library.rs b/src/shell/library.rs
index bcb8aa7a74c8009b12a87c90f42610c9da6380b3..986811eb1ad9e4f55d29243ff1313ea78eda2a55 100644
--- a/src/shell/library.rs
+++ b/src/shell/library.rs
@@ -1,4 +1,5 @@
 use super::{Binary, FlowLogic, Shell};
+use super::status::*;
 use std::fs::File;
 use std::io::{self, Read};
 use std::path::Path;
@@ -23,7 +24,9 @@ impl<'a> IonLibrary for Shell<'a> {
         let capacity = file.metadata().ok().map_or(0, |x| x.len());
         let mut command_list = String::with_capacity(capacity as usize);
         let _ = file.read_to_string(&mut command_list)?;
-        self.terminate_script_quotes(command_list.lines().map(|x| x.to_owned()));
+        if FAILURE == self.terminate_script_quotes(command_list.lines().map(|x| x.to_owned())) {
+            self.previous_status = FAILURE;
+        }
         Ok(self.previous_status)
     }
 }
diff --git a/src/shell/mod.rs b/src/shell/mod.rs
index 93ab6870937426648ea5c8d06b3dd1d330cd169b..cc58c492dce66784c506d03f0719d9625e462e39 100644
--- a/src/shell/mod.rs
+++ b/src/shell/mod.rs
@@ -237,7 +237,11 @@ impl<'a> Shell<'a> {
                 }
                 let borrowed = &pipeline.jobs[0].args;
                 let small: SmallVec<[&str; 4]> = borrowed.iter().map(|x| x as &str).collect();
-                Some((command.main)(&small, self))
+                if self.flags & NO_EXEC != 0 {
+                    Some(SUCCESS)
+                } else {
+                    Some((command.main)(&small, self))
+                }
             } else {
                 Some(self.execute_pipeline(pipeline))
             }
diff --git a/src/shell/pipe_exec/mod.rs b/src/shell/pipe_exec/mod.rs
index 2f9de2c877558edea2057e5d47794e227a63e182..e9a15630b342532863feb23e9308233984513a1f 100644
--- a/src/shell/pipe_exec/mod.rs
+++ b/src/shell/pipe_exec/mod.rs
@@ -182,7 +182,8 @@ pub(crate) trait PipelineExecution {
     ///
     /// Each generated command will either be a builtin or external command, and will be
     /// associated will be marked as an `&&`, `||`, `|`, or final job.
-    fn generate_commands(&self, pipeline: &mut Pipeline) -> Result<Vec<(RefinedJob, JobKind)>, i32>;
+    fn generate_commands(&self, pipeline: &mut Pipeline)
+        -> Result<Vec<(RefinedJob, JobKind)>, i32>;
 
     /// Waits for all of the children within a pipe to finish exuecting, returning the
     /// exit status of the last process in the queue.
@@ -232,8 +233,14 @@ impl<'a> PipelineExecution for Shell<'a> {
         // Generates commands for execution, differentiating between external and builtin commands.
         let mut piped_commands = match self.generate_commands(pipeline) {
             Ok(commands) => commands,
-            Err(error) => return error
+            Err(error) => return error,
         };
+
+        // Don't execute commands when the `-n` flag is passed.
+        if self.flags & NO_EXEC != 0 {
+            return SUCCESS;
+        }
+
         // Redirect the inputs if a custom redirect value was given.
         if let Some(stdin) = pipeline.stdin.take() {
             if redirect_input(stdin, &mut piped_commands) {
@@ -263,7 +270,10 @@ impl<'a> PipelineExecution for Shell<'a> {
         }
     }
 
-    fn generate_commands(&self, pipeline: &mut Pipeline) -> Result<Vec<(RefinedJob, JobKind)>, i32> {
+    fn generate_commands(
+        &self,
+        pipeline: &mut Pipeline,
+    ) -> Result<Vec<(RefinedJob, JobKind)>, i32> {
         let mut results = Vec::new();
         for mut job in pipeline.jobs.drain(..) {
             let refined = {
diff --git a/src/sys/redox.rs b/src/sys/redox.rs
index 91233c5c145f527b41da16fd85b4d7f0f7692742..52f95de9c270f79707e1a0339afec17267fff497 100644
--- a/src/sys/redox.rs
+++ b/src/sys/redox.rs
@@ -43,6 +43,7 @@ pub(crate) fn setpgid(pid: u32, pgid: u32) -> io::Result<()> {
     cvt(syscall::setpgid(pid as usize, pgid as usize)).and(Ok(()))
 }
 
+#[allow(dead_code)]
 pub(crate) fn signal(signal: i32, handler: extern "C" fn(i32)) -> io::Result<()> {
     let new = SigAction {
         sa_handler: unsafe { mem::transmute(handler) },
@@ -98,14 +99,14 @@ fn cvt(result: Result<usize, syscall::Error>) -> io::Result<usize> {
 
 // TODO
 pub mod signals {
-    pub(crate) fn block() // fn block() // fn block() // fn block() // fn block()
+    pub(crate) fn block() // fn block() // fn block()
     {
     }
 
     /// Unblocks the SIGTSTP/SIGTTOU/SIGTTIN/SIGCHLD signals so children processes can be
     /// controlled
     /// by the shell.
-    pub(crate) fn unblock() // fn unblock() // fn unblock() // fn unblock() // fn unblock()
+    pub(crate) fn unblock() // fn unblock() // fn unblock()
     {
     }
 }
diff --git a/src/sys/unix.rs b/src/sys/unix.rs
index 61c838949479ca6f86ba556af13baf0eae109859..fbf7919691bfbb38cf76653d691efedebeac02f8 100644
--- a/src/sys/unix.rs
+++ b/src/sys/unix.rs
@@ -48,6 +48,7 @@ pub(crate) fn setpgid(pid: u32, pgid: u32) -> io::Result<()> {
     cvt(unsafe { libc::setpgid(pid as pid_t, pgid as pid_t) }).and(Ok(()))
 }
 
+#[allow(dead_code)]
 pub(crate) fn signal(signal: i32, handler: extern "C" fn(i32)) -> io::Result<()> {
     if unsafe { libc::signal(signal as c_int, handler as sighandler_t) } == libc::SIG_ERR {
         Err(io::Error::last_os_error())
@@ -105,7 +106,9 @@ fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
 pub mod signals {
     /// Blocks the SIGTSTP/SIGTTOU/SIGTTIN/SIGCHLD signals so that the shell never receives
     /// them.
-    pub(crate) fn block() // fn block() // fn block() // fn block() // fn block()
+    pub(crate) fn block()
+    // fn block() // fn block() // fn block() // fn block() // fn block() //
+    // fn block()
     {
         unsafe {
             use libc::*;
@@ -124,7 +127,10 @@ pub mod signals {
     /// Unblocks the SIGTSTP/SIGTTOU/SIGTTIN/SIGCHLD signals so children processes can be
     /// controlled
     /// by the shell.
-    pub(crate) fn unblock() // fn unblock() // fn unblock() // fn unblock() // fn unblock()
+    pub(crate) fn unblock()
+    // fn unblock()
+    // fn unblock() // fn unblock() // fn unblock() // fn unblock() // fn
+    // unblock()
     {
         unsafe {
             use libc::*;