October 8, 2025
Jlon — A Smarter JupyterLab Launch Command

Streamlining the Start

I use JupyterLab daily ever since I discovered all the things I can automate using code. But this isn’t a regular part of my day, between google ads, various ad platforms, organic dashboards and crm workflows it’s not always easy for me to snap back to remembering all the things I need to do to keep my notebooks, scripts and the micro tools i create to be organized and the last thing I want is to find the 15 different final versions of a script i’ve been working on which i didn’t bother naming properly and ofcourse this can all be solved with a little discipline but it’s something that i’m cultivating but a little help can go a long way.

So while I’m doing something else, I don’t want to stop and think through cd, venv, start notebooks. I just want to open the right folder and keep moving and i don’t want to cd, venv, start notebooks navigate to the right folder and make sure my files are saved in the right place. I just decided to make a simple command to do just that and to help me jump in easily.

I didn’t want to make things complicated or type an extremely long command jlon is easy to remember does exactly what it says “JyupterLabs On”, One command opens JupyterLab in the correct folder, activates your environment, and spins up the server automatically. asks me which folder I want to start from and opens the browser.

The jlon Command

Here is what happens, step by step:

  • Activates my Python virtual environment from ~/Documents/projects/jl/bin/activate so the right dependencies load every time.
  • Uses fzf to let me pick the project folder, for example notebooksscriptscheckers, or cron.
  • Checks for a free port between 8888 and 8899 so it does not collide with another Jupyter server.
  • Starts JupyterLab in the background with nohup and writes output to ~/.jupyterlab.log.
  • Reads the correct tokenized URL from jupyter server list and opens it with open on macOS.
  • Saves the process ID in ~/.jupyterlab.pid so jloff can stop the exact server later.

Setup: Add the Command to Your Shell

Copy the block below into your ~/.zprofile or ~/.zshrc. Reload your shell with source ~/.zprofile or restart Terminal. The comments explain each step so you can adjust paths and behavior without guessing.

Prerequisites:

  • Python with JupyterLab installed
  • fzf installed with Homebrew (brew install fzf)
  • Your virtual environment at ~/Documents/projects/jl/bin/activate or update the path in the script
# JupyterLab quick launcher and stopper
# Author: Dan Antony
# macOS Sequoia | zsh

# Paths
export JL_LOG_FILE="$HOME/.jupyterlab.log"     # last launch output
export JL_PID_FILE="$HOME/.jupyterlab.pid"     # PID for clean stop

# Start JupyterLab
jupyter_lab_launch() {
  # 1. Activate Python environment
  local VENV_ACT="$HOME/Documents/projects/jl/bin/activate"
  if [[ -f "$VENV_ACT" ]]; then
    source "$VENV_ACT"
  else
    echo "Virtual environment not found at $VENV_ACT"
  fi

  # 2. Choose project folder
  local base="$HOME/Documents/projects"
  local folders=(notebooks scripts checkers cron)
  local existing=()
  local f
  for f in "${folders[@]}"; do
    [[ -d "$base/$f" ]] && existing+=("$f")
  done
  if [[ ${#existing[@]} -eq 0 ]]; then
    mkdir -p "$base/notebooks"
    existing=("notebooks")
  fi
  local selected=""
  if command -v fzf >/dev/null 2>&1; then
    selected="$(printf "%s\n" "${existing[@]}" | fzf --prompt='Select folder: ')"
  fi
  selected=${selected:-notebooks}
  cd "$base/$selected" || { echo "Cannot access folder $base/$selected"; return 1; }

  # 3. Find open port 8888-8899
  local port=""
  local p
  for p in {8888..8899}; do
    if ! lsof -iTCP:"$p" -sTCP:LISTEN -nP >/dev/null 2>&1; then
      port="$p"
      break
    fi
  done
  if [[ -z "$port" ]]; then
    echo "No open port found in 8888 to 8899"
    return 1
  fi

  # 4. Launch JupyterLab in background
  if ! command -v jupyter >/dev/null 2>&1; then
    echo "jupyter is not in PATH"
    return 1
  fi
  : > "$JL_LOG_FILE"
  nohup jupyter lab --notebook-dir="$PWD" --port="$port" --no-browser >"$JL_LOG_FILE" 2>&1 &
  local pid=$!
  echo "$pid" > "$JL_PID_FILE"
  echo "Started JupyterLab (PID $pid) in $PWD on port $port"

  # 5. Find tokenized URL for this directory
  local url=""
  local i
  for i in {1..24}; do
    sleep 0.5
    url="$(jupyter server list 2>/dev/null | awk -v here="$PWD" -F ' :: ' 'NF==2{u=$1;r=$2;if(r==here){print u;exit}}')"
    [[ -n "$url" ]] && break
  done
  [[ -z "$url" ]] && url="$(jupyter server list 2>/dev/null | awk 'NR==1{print $1}')"

  if [[ -n "$url" ]]; then
    echo "Opening $url"
    open "$url"
  else
    echo "Could not detect server URL. Check $JL_LOG_FILE"
  fi
}

# Stop JupyterLab
jupyter_lab_stop() {
  local pid=""
  if [[ -f "$JL_PID_FILE" ]]; then
    pid="$(cat "$JL_PID_FILE")"
  fi
  if [[ -n "$pid" && $(ps -p "$pid" -o pid=) ]]; then
    echo "Stopping JupyterLab (PID $pid)"
    kill "$pid" && sleep 1
    if ps -p "$pid" >/dev/null; then
      kill -9 "$pid"
    fi
  else
    pkill -f jupyter-lab
  fi
  rm -f "$JL_PID_FILE"
}

# Aliases
alias jlon="jupyter_lab_launch"
alias jloff="jupyter_lab_stop"
alias jlst="jupyter server list"
alias jllog="tail -n 100 $JL_LOG_FILE"

For Clarity:

  • fzf: a terminal fuzzy finder. You type a few letters and it filters the list. Install it with brew install fzf.
  • nohup: runs a command so it keeps going even if you close the terminal. We use it so JupyterLab does not die when the tab closes.
  • lsof: lists open files and listening ports. We use it to find a free port.
  • open: macOS command that opens a URL in your default browser.
  • PID file: a small file that stores the process ID so you can stop the right server later.
  • tokenized URL: Jupyter includes a token in the URL for auth. We do not parse logs. We ask jupyter server list for the current URL.

How to use it:

  1. Paste the script into ~/.zprofile or ~/.zshrc and reload your shell.
  2. In any terminal window, run jlon. Pick a folder when prompted.
  3. Your browser opens to JupyterLab for that folder. When done, run jloff.

Example Run

$ jlon
Select folder: scripts
Started JupyterLab (PID 19321) on port 8888
Opening: http://localhost:8888/?token=bb7e123abcd...

$ jloff
Stopping JupyterLab (PID 19321)...

Every time you use it, Jupyter opens exactly where you left off, organized, activated, and ready to go.

The best shortcuts are not flashy. They just disappear into your workflow. jlon turned a multi-step start into a single, predictable command. That is all I needed.

Dan.Marketing
Dan.marketing is the personal website of Daniel (Dan) Antony, a digital marketer passionate about business and technology
STAY IN TOUCH
© Copyright 2025 - All Rights Reserved
Bengaluru, KA 560017
+91-9353346840
mail@dan.marketing