Skip to content

Instantly share code, notes, and snippets.

@msfeldstein
Last active January 4, 2019 23:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msfeldstein/19e9315f9f7bb1c093f98b27d1920902 to your computer and use it in GitHub Desktop.
Save msfeldstein/19e9315f9f7bb1c093f98b27d1920902 to your computer and use it in GitHub Desktop.

Persistent SSH Sessions with tmux

I use my raspberry pi exclusively over ssh. While it's great to be able to use my regular laptop to control my pi, ssh has some downsides:

  • Difficult to start long-running processes
  • Lose all your state when you close your laptop
  • Need to re-ssh in every new tab

tmux is a terminal multiplexer which is a program that can manage terminal sessions for you. We can start a session on login of your pi, and then whenever we ssh in we can automatically connect to that same session. When you log out and re-connect, you'll get the same terminal windows with the same processes still running. Suddenly those problems are now features:

  • Run long-running programs without worrying about your terminal closing and killing it
  • Log back into exactly where you last left it
  • Use iTerm's native tmux integration to just cmd+t/n new ssh terminal windows

I've only really used this with iTerm. If you use a different terminal, it doesn't have tmux integration and you have to learn all the tmux commands which is a bit more complicated.

How do?

First lets make sure tmux is installed. On your pi, install with apt:

sudo apt-get update
sudo apt-get install tmux

We need to start a tmux server automatically when you start up your pi. We can do that with rc.local. First, lets create a script that will start the server for us.

/home/pi/start_tmux.sh

#!/bin/bash

# Use the complete path to tmux since rc.local doesn't necessarily have access to your path at boot
/usr/bin/tmux new-session -d -s mySession
# This statement is a life-saver, if ever your code crashes
/usr/bin/tmux set-option -t mySession set-remain-on-exit on
# Set the default command to bash otherwise you'll have a barebones non-bash terminal
/usr/bin/tmux set-option -g default-command bash

Make this script executable so we can launch it from rc.local.

$ chmod +x start_tmux.sh

Now we need to run it in rc.local. Since rc.local is not run as your user, its slightly more complicated to start this correctly. Add the following line to /etc/rc.local, and ensure rc.local is executable.

/etc/rc.local

su -c "/home/pi/start_tmux.sh" -s /bin/sh pi

This will launch the script as your user, and have the tmux server available (assuming you're still logged in as pi). Now we need to tell any new ssh connections to use the tmux screens. Add this line to your bash_profile.

/home/pi/.bash_profile

[ -z "$TMUX" ] && { exec tmux -CC && exit;}

This tells your bash shell "If we're not in TMUX already, run tmux under control mode (-CC)". If we didn't check to see if we were in tmux already, we would be in an infinite loop of loading new tmux shells from every new tmux shell. If you're not using iTerm, take out the -CC flags (i haven't tested it without iTerm much).

Now, when you ssh into your pi from iTerm, you'll have fully native, persistent terminal windows.

Let me know if this is useful, or if you're running into issues.

@msfeldstein

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment