How to source virtualenv activate in a Bash script
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
To activate a Python virtual environment inside a Bash script, use source /path/to/venv/bin/activate. The source command (or its shorthand .) executes the activate script in the current shell context, modifying PATH and PS1 so that subsequent commands use the virtual environment's Python and packages. A common mistake is running activate as a subprocess (without source), which activates the environment in a child shell that exits immediately, leaving the parent script unaffected.
Basic Usage
The source command runs activate in the current shell process, so PATH changes persist for the rest of the script.
Why source Is Required
Without source, the script runs activate in a subprocess. When that subprocess exits, all environment changes (PATH, VIRTUAL_ENV, etc.) are discarded.
Using Absolute Paths
For scripts that may run from any directory, use absolute paths:
Check that the activate script exists before sourcing to provide a clear error message.
Script-Relative Paths
Activate relative to the script's own location:
${BASH_SOURCE[0]} gives the path to the script itself, regardless of where it was called from.
CI/CD Pipeline Example
In CI pipelines, always use set -e to fail fast if any command errors.
Using with Cron Jobs
Cron jobs do not load shell profiles, so activate the virtual environment explicitly:
Alternatively, skip activation entirely and call the venv's Python directly:
This is simpler for cron jobs and scripts that only run a single Python command.
POSIX sh Compatibility
The source command is a Bash builtin. For /bin/sh scripts, use . instead:
The . command is POSIX-compliant and works in all Bourne-compatible shells.
Common Pitfalls
- Running
activatewithoutsource: Executing./venv/bin/activateorbash venv/bin/activateruns it in a subprocess. The environment changes are lost when the subprocess exits. Always usesourceor.to run it in the current shell. - Hardcoding paths that differ between environments: A script with
source /home/alice/venv/bin/activatebreaks when run by a different user or on a different machine. Use script-relative paths with${BASH_SOURCE[0]}or environment variables. - Forgetting that cron jobs have minimal PATH: Cron does not load
.bashrcor.profile. Thepython3andpipcommands may not be found. Either activate the venv in the script or use the full path to the venv's Python binary. - Not checking if the virtual environment exists: If the venv directory is missing or corrupted,
source venv/bin/activatefails silently or with a confusing error. Check[ -f venv/bin/activate ]before sourcing and exit with a clear message if it is missing. - Using
sourcein a#!/bin/shscript: Thesourcebuiltin is not available in POSIXsh. Use. venv/bin/activate(dot-space) instead, which is POSIX-compliant and works in all shells.
Summary
- Use
source venv/bin/activate(or. venv/bin/activate) to activate a virtualenv in a Bash script sourceruns the script in the current shell; without it, changes are lost in a subprocess- Use absolute or script-relative paths for portability across environments
- For cron jobs, either activate in the script or call the venv's Python directly (
venv/bin/python) - Check that the activate file exists before sourcing to catch missing environments early
- Use
.instead ofsourcefor POSIXshcompatibility

