How to make Python virtual environments easier to use

An AI image. You aren't missing anything.
An AI image of the cool vaporwave office that I used to work at, in my dreams.

This script has it all. Remember the blog post about using python in a shell script? It was called  How to use python in a bash script . I use that technique in the script. It is a blast from the past!

setenv.sh: This code is also available as a Github Gist: setenv.sh .

[Update July 12, 2025: I have made is source code public domain. Don't ever tell anyone where you got it. People often confuse the authors of installer programs with the authors of the installed programs. So, while I think that I have written a useful and novel script that I would like to get credit for, I don't want your tech support calls. ]

#!/bin/bash
# Easy script to create a python venv and install requirements
# or run the venv if it already exists.

# Use this as the base for your python programs.
#  Features:
#   * It auto-detects a python venv (any venv, so be careful).
#   * It prompts the user before installing software.
#   * It automatically activates the venv if one exists. This is
#     so nice for the user because then they can run the program
#     without having to source the activate script.
#
# There are two ways to use this:
#  * You can set this up to install/activate a venv by sourcing
#    this file. This is for the programmer.
#  * You can "chmod +x" this file so that the venv is activated
#    in a subshell which then can run a python program. When the
#    subshell exits, the venv will not be active. This is what
#    your users expect.

FULL_PATH_TO_SCRIPT="$(realpath "$0")"
SCRIPT_DIRECTORY="$(dirname "$FULL_PATH_TO_SCRIPT")"

# VENV detection and activation.
 function detect-venv   () {
  python -c 'if 1:#for indentation
  import sys
  ss=sys.prefix != sys.base_prefix
  # print("%s\n%s\n%s" % (sys.prefix,sys.base_prefix,ss) )
  if ss:
   sys.exit(0)
  sys.exit(1)
  '
  return $?
  }
 function activate-venv () {
  # shellcheck disable=SC1091
  source "$SCRIPT_DIRECTORY"/venv/bin/activate || true;
  detect-venv
  VENV=$?
  if [ $VENV = 1 ]; then
   echo "No venv available."
   echo "Need a venv and these python dependencies:"
   echo ""
   sed 's/^/  /' "$SCRIPT_DIRECTORY"/requirements.txt
   echo ""
   echo ""
   read -rp "Do you want to create a python venv and install python dependencies (y/n) " response
   case ${response:0:1} in
    y|Y )
     echo "Creating venv..."
     python -m venv "$SCRIPT_DIRECTORY"/venv
     echo "Activating venv."
     # shellcheck disable=SC1091
     source "$SCRIPT_DIRECTORY"/venv/bin/activate
     # Sanity check, then Install python dependencies:
     detect-venv
     VENV=$?
     if [ $VENV = 1 ]; then
      echo "No active venv. Refusing to procede."
      return 1
      fi
     : \
     && echo 'Installing python libraries.' \
     && python -m pip install -r "$SCRIPT_DIRECTORY"/requirements.txt \
     ;
     ;;
    n|N )
     echo "Ok, no action taken."
     ;;
    * )
     echo "Ok, no action taken."
     ;;
   esac
   unset response
   fi
  unset VENV
  }
 function run-app       () {
  # shellcheck disable=SC2078
  if [ "Run your program:" ]; then
   # Sanity check:
   detect-venv
   VENV=$?
   if [ $VENV = 1 ]; then
    echo "No active venv. Refusing to procede."
    return 1
    fi
   # Put your script logic here:
   echo "Put your script logic here."
   # "$SCRIPT_DIRECTORY"/your-script "$@"
   fi
  }

activate-venv
run-app "$@"

So, in conclusion, if you are doing this in any other way, you are doing it wrong.

So, yeah, I did this and it changed my life.

Comments:

🥊@HughHacker  3 minutes ago.
sam8077, I have updated the script and the github gist with a fix.

😎@sam8077  11 minutes ago.
It says it can't find the requirements file.

🥰@cousin-larry9877  40 minutes ago.
Wow, I've never though of it that way before.

🎮@cleopatrick0378  57 minutes ago.
Mr. Hugh Hacker, you are so great.

🎮@iceberg8025  60 minutes ago.
Truly the greatest script ever sir. I use this script to great effect in my life.