Startup script for tmux session

A while back I was converted from using OS tabs in the macOS Terminal to tmux, a terminal multiplexer (hence the name). This gives the ability to have multiple sessions (terminal sessions), windows (terminal tabs), and panes within a single window (no stock counterpart), among many other things. I’ve gotten to the point where I’m fairly efficient in it, but I’m sure there are a million more features that I’m not taking advantage of yet.

One of the annoyances I dealt with was that I had to set up my session, windows, and panes after every reboot. macOS is technically better than tmux default behavior in this regard, since it would at least remember the tab directories that I had open before and restore the session context in each. With tmux, I found my self typing the same annoying session setup commands after a reboot (this pain was at a peak when I was testing server auto-restarts on my Pi and was rebooting manually constantly).

Below is the relatively simple bash script that I wrote to handle setup. It opens 5 different windows in different directories, splits a couple into 2 panes, and and sets up any virtual environments + environment variables I need for that specific window. It’s pretty barebones, doing minimal configuration with each window and pane. There is way more customization available through the send-keys and other tmux commands, like arranging panes or executing scripts. It can be super useful for setting up different environment variables or virtual environments like I do for the ESP window (looking at you python users) to avoid having to clutter up your .bash_profile/.bash_rc with a ton of variable declarations. This version is the one I have on my personal laptop since I don’t run anything continuous on it that needs to be spun up automatically. On my Raspberry Pi, the script has a few extra lines per-window to execute a bash script in each opened window to start up different webservers since that tmux startup script runs headlessly.

This script can be configured to run at boot through many different channels. Anything from a cron @reboot to rc.local and even systemd will work. There are plenty of write-ups on the pros/cons of each online.

Yes, I understand there are improvements and better practices that could separate out some logic here. The goal is not to have the most modular, precise script ever, but to be simple and straightforward.

#!/bin/bash

SESSION_NAME="main"
SCRATCH_WINDOW_NAME="scratch"
NODE_WINDOW_NAME="node"
WEBSITE_WINDOW_NAME="brian.team"
ESP_8266_WINDOW_NAME="esp8266"
ESP_32_WINDOW_NAME="esp32"
PI_WINDOW_NAME="pi"

# Check to see if we're already running the session
tmux has-session -t $SESSION_NAME &> /dev/null

if [ $? != 0 ] ; then
    # Create overall tmux session
    tmux new-session -d -s $SESSION_NAME > /dev/null

    # Since we get one window for free on creation, rename it to our scratch windowe
    tmux rename-window -t $SESSION_NAME:0 $SCRATCH_WINDOW_NAME
    tmux send-keys -t $SESSION_NAME:0 "cd ~/Developer" C-m

    # Create window for running webserver
    tmux new-window -t $SESSION_NAME:1 -n $NODE_WINDOW_NAME
    tmux send-keys -t $SESSION_NAME:1 "cd ~/Developer" C-m

    # Create window for brian.team website dev
    tmux new-window -t $SESSION_NAME:2 -n $WEBSITE_WINDOW_NAME
    tmux send-keys -t $SESSION_NAME:2 "cd ~/Developer/brian.team" C-m
    tmux split-window -v -p 30 -t $SESSION_NAME:2

    # Create 2 windows for esp dev, one for 32 one for 8266
    tmux new-window -t $SESSION_NAME:3 -n $ESP_8266_WINDOW_NAME
    tmux send-keys -t $SESSION_NAME:3 "cd ~/Developer/esp" C-m
    tmux send-keys -t $SESSION_NAME:3 "source .venv/bin/activate" C-m
    tmux send-keys -t $SESSION_NAME:3 "export IDF_PATH=~/Developer/esp/ESP8266_RTOS_SDK" C-m
    tmux split-window -v -p 30 -t $SESSION_NAME:3

    tmux new-window -t $SESSION_NAME:4 -n $ESP_32_WINDOW_NAME
    tmux send-keys -t $SESSION_NAME:4 "cd ~/Developer/esp" C-m
    tmux send-keys -t $SESSION_NAME:4 "source .venv/bin/activate" C-m
    tmux send-keys -t $SESSION_NAME:4 "export IDF_PATH=~/Developer/esp/esp-idf" C-m
    # gdb-tui fails to start within tmux with our normal TERM=screen-256color env var
    tmux send-keys -t $SESSION_NAME:4 "export TERM=xterm-256color" C-m
    # use custom interface cfg and specify target file for use with 'idf.py openocd' jtag debug server
    tmux send-keys -t $SESSION_NAME:4 "export OPENOCD_COMMANDS=\"-f /Users/brianteam/Developer/esp/custom_f232_interface.cfg -f target/esp32.cfg\"" C-m

    tmux send-keys -t $SESSION_NAME:4 "source ~/Developer/esp/esp-idf/export.sh" C-m
    tmux split-window -v -p 30 -t $SESSION_NAME:4

    # Create window for pi control
    tmux new-window -t $SESSION_NAME:5 -n $PI_WINDOW_NAME
    tmux send-keys -t $SESSION_NAME:5 "cd ~" C-m
else
    echo "tmux session already running, attaching..."
    sleep 2
fi

tmux attach