12

Being an avid Linux user prior to buying a MacBook Pro, I typically have several terminal tabs open at any one time.

In the past, crashes and reboots would generally trash my workflow, and the majority of my respective tab histories. I searched for ways to solve this problem but always came up empty; aside from various techniques that utilised combinations of tools like ssh, screen, tmux, and required a virtual private server (or similar).

One of my favourite things about using my MacBook Pro for writing scripts, and using CLI tools, etc; is that my terminal sessions persist beyond crashes and reboots by default. In fact, I just restored a backup from almost 2 years ago, and when I logged in for the first time, I was presented with my old desktop and three bash shells that comprised a project that I was working on all that time ago.

I would like to know how OS X makes this feature possible. Does anybody here have insight into how it works?

10

The code to restore Terminal (actually bash sessions) is part of /etc/bashrc_Apple_Terminal which gets sourced through /etc/profile and /etc/bashrc for each bash session running in Terminal.

# Resume Support: Save/Restore Shell State
#
# Terminal assigns each terminal session a unique identifier and
# communicates it via the TERM_SESSION_ID environment variable so that
# programs running in a terminal can save/restore application-specific
# state when quitting and restarting Terminal with Resume enabled.
#
# The following code defines a shell save/restore mechanism. Users can
# add custom state by defining a shell_session_save_user_state function
# that writes restoration commands to the session file at exit. e.g.,
# to save a variable:
#
#   shell_session_save_user_state() { echo MY_VAR="'$MY_VAR'" >> "$SHELL_SESSION_FILE"; }
#
# During shell startup the session file is executed. Old files are
# periodically deleted.
#
# The default behavior arranges to save and restore the bash command
# history independently for each restored terminal session. It also
# merges commands into the global history for new sessions. Because
# of this it is recommended that you set HISTSIZE and HISTFILESIZE to
# larger values.
#
# You may disable this behavior and share a single history by setting
# SHELL_SESSION_HISTORY to 0. There are some common user customizations
# that arrange to share new commands among running shells by
# manipulating the history at each prompt, and they typically include
# 'shopt -s histappend'; therefore, if the histappend shell option is
# enabled, per-session history is disabled by default. You may
# explicitly enable it by setting SHELL_SESSION_HISTORY to 1.
#
# The implementation of per-session command histories in combination
# with a shared global command history is incompatible with the
# HISTTIMEFORMAT variable--the timestamps are applied inconsistently
# to different parts of the history; therefore, if HISTTIMEFORMAT is
# defined, per-session history is disabled by default.
#
# Note that this uses PROMPT_COMMAND to enable per-session history
# the first time for each new session. If you customize PROMPT_COMMAND
# be sure to include the previous value. e.g.,
#
#   PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND; }your_code_here"
#
# Otherwise, the per-session history won't take effect until the first
# restore.
#
# The save/restore mechanism is disabled if the following file exists:
#
#   ~/.bash_sessions_disable
  • 1
    Cool, so are these comments from /etc/bashrc_Apple_Terminal? I especially like that # The default behavior arranges to save and restore the bash command history independently for each restored terminal session. It also # merges commands into the global history for new sessions. That's something else I've tried to implement before, but to no avail. – tjt263 Apr 5 '17 at 4:56
  • So anyway I want to mark this as the answer, but I've been reading through this file and ..can you point out the specific lines of code that cause this effect? There seems to be more to it than just the functions mentioned in the comments. It could just be my tired eyes, but I can't make much sense of it. – tjt263 Jan 29 '18 at 11:41
  • @tjt263 Never found time to figure that out yet – nohillside Jan 29 '18 at 12:37
  • @tjt263 It's everything from the comment til the end of the file, actually. Basically it uses trap to catch the end of a session and store its history in a tab/session specific file. – nohillside Jan 29 '18 at 19:19
5

As far as I can tell, it just saves the text in each window's scrollback buffer. It doesn't actually save the state of what was running in the terminals; it just starts a new shell after the reboot.

As an experiment, define a variable in your shell, and check its value:

foo=bar
echo $foo

Then reboot, and check the variable's value again. You'll see that it's no longer defined.

  • Whew! That would have been creepy otherwise. – uhoh Apr 2 '17 at 14:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .