diff --git a/src/lib/builtins/mod.rs b/src/lib/builtins/mod.rs
index 9dc3d541bad4764758b94564c94923f0898bdd4c..a526174dc8b6b57c43061bdb92a2396716dcb511 100644
--- a/src/lib/builtins/mod.rs
+++ b/src/lib/builtins/mod.rs
@@ -594,8 +594,7 @@ fn builtin_exit(args: &[small::String], shell: &mut Shell) -> i32 {
             let _ = sys::kill(process.pid, sys::SIGTERM);
         }
     }
-    let previous_status = shell.previous_status;
-    shell.exit(args.get(1).and_then(|status| status.parse::<i32>().ok()).unwrap_or(previous_status))
+    shell.exit(args.get(1).and_then(|status| status.parse::<i32>().ok()))
 }
 
 fn builtin_exec(args: &[small::String], shell: &mut Shell) -> i32 {
diff --git a/src/lib/shell/binary/readln.rs b/src/lib/shell/binary/readln.rs
index 2df7f021d5a1b139ebe9119929162a6363795782..d486db083b1c9eba0926a9a487d986059c21f8d3 100644
--- a/src/lib/shell/binary/readln.rs
+++ b/src/lib/shell/binary/readln.rs
@@ -109,8 +109,7 @@ pub fn readln(binary: &InteractiveBinary) -> Option<String> {
             } else if shell.flow_control.pop() {
                 None
             } else {
-                let status = shell.previous_status;
-                shell.exit(status);
+                shell.exit(None);
             }
         }
         Err(err) => {
diff --git a/src/lib/shell/flow.rs b/src/lib/shell/flow.rs
index 18ffbbd8a04c33e9a86cb1033db7cb52ef840a90..9f8713c037de2ddddd449cf23e185635aad297e9 100644
--- a/src/lib/shell/flow.rs
+++ b/src/lib/shell/flow.rs
@@ -181,8 +181,7 @@ impl<'a> Shell<'a> {
                         self.run_pipeline(pipeline);
                     }
                     if self.opts.err_exit && self.previous_status != SUCCESS {
-                        let status = self.previous_status;
-                        self.exit(status);
+                        self.exit(None);
                     }
                     if !statements.is_empty() {
                         self.execute_statements(&statements);
@@ -258,7 +257,7 @@ impl<'a> Shell<'a> {
         }
         if let Some(signal) = signals::SignalHandler.next() {
             if self.handle_signal(signal) {
-                self.exit(get_signal_code(signal));
+                self.exit(Some(get_signal_code(signal)));
             }
             Condition::SigInt
         } else if self.break_flow {
diff --git a/src/lib/shell/mod.rs b/src/lib/shell/mod.rs
index 5a635117aa53e03baddb11434aa8622a733409dd..2a698b18a36538607ad6872cc89e9d896120d5ea 100644
--- a/src/lib/shell/mod.rs
+++ b/src/lib/shell/mod.rs
@@ -95,7 +95,7 @@ pub struct Shell<'a> {
     directory_stack: DirectoryStack,
     /// When a command is executed, the final result of that command is stored
     /// here.
-    pub previous_status: i32,
+    previous_status: i32,
     /// The job ID of the previous command sent to the background.
     previous_job: u32,
     /// Contains all the options relative to the shell
@@ -107,7 +107,7 @@ pub struct Shell<'a> {
     pub unterminated: bool,
     /// Set when a signal is received, this will tell the flow control logic to
     /// abort.
-    pub(crate) break_flow: bool,
+    break_flow: bool,
     /// When the `fg` command is run, this will be used to communicate with the specified
     /// background process.
     foreground_signals: Arc<ForegroundSignals>,
@@ -446,9 +446,9 @@ impl<'a> Shell<'a> {
     pub fn variables_mut(&mut self) -> &mut Variables<'a> { &mut self.variables }
 
     /// Cleanly exit ion
-    pub fn exit(&mut self, status: i32) -> ! {
+    pub fn exit(&mut self, status: Option<i32>) -> ! {
         self.prep_for_exit();
-        process::exit(status);
+        process::exit(status.unwrap_or(self.previous_status));
     }
 
     pub fn assign(&mut self, key: &Key, value: Value<'a>) -> Result<(), String> {
diff --git a/src/lib/shell/pipe_exec/job_control.rs b/src/lib/shell/pipe_exec/job_control.rs
index a59e9c4be6630aeb9be53f5516cefbabf622e898..8aa3cc77ab9e8d4889bac86b0efe4d946985a38e 100644
--- a/src/lib/shell/pipe_exec/job_control.rs
+++ b/src/lib/shell/pipe_exec/job_control.rs
@@ -257,7 +257,7 @@ impl<'a> Shell<'a> {
         while self.background.lock().unwrap().iter().any(|p| p.state == ProcessState::Running) {
             if let Some(signal) = signals::SignalHandler.find(|&s| s != sys::SIGTSTP) {
                 self.background_send(signal);
-                self.exit(get_signal_code(signal));
+                self.exit(Some(get_signal_code(signal)));
             }
             sleep(Duration::from_millis(100));
         }
diff --git a/src/main.rs b/src/main.rs
index 6b16b0a89102272afae907a891f1077ff246b2d2..4e2b97e49e49fed439ec561bb6accc28cbc624e7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -84,5 +84,5 @@ fn main() {
         shell.execute_script(BufReader::new(stdin()));
     }
     shell.wait_for_background();
-    shell.exit(shell.previous_status);
+    shell.exit(None);
 }