Mastering Python Execution: Running Python Scripts from the Terminal
Working in Python? Eventually, you’ll need to run your scripts outside an IDE—perhaps on a production server, as a scheduled job, or in a CI/CD pipeline. The terminal is where these tasks become explicit: version management, reproducible execution, and direct control.
Direct Execution: The Core Command
The fundamental invocation pattern:
python3 script.py
Or if you're on Windows and installed via the official Python.org installer:
py script.py
Note: On many Linux distributions, python
refers to Python 2.x, which is deprecated (python --version
to confirm). Always prefer python3
unless you have a strong reason otherwise.
Python Version Management
Multiple Python versions lead to ambiguity:
$ python --version
Python 2.7.18
$ python3 --version
Python 3.10.12
If your build targets 3.x (as virtually all modern code does), never rely on an unqualified python
unless you’ve updated your alternatives
or symlinks accordingly. On macOS Ventura+ and Ubuntu 22.04+, python
may not be configured at all.
Shebangs and Executable Scripts (POSIX)
Tired of typing python3
each time? Add a shebang to your script's first line:
#!/usr/bin/env python3
Make it executable:
chmod +x my_job.py
Now execution becomes OS-agnostic (given a compliant env
):
./my_job.py
This avoids hardcoding absolute interpreter paths, which may drift between virtual environments and system upgrades.
Gotcha: On some systems, shebang line length is limited (usually 127 chars). Overly deep Python installations may cause /usr/bin/env: bad interpreter
errors.
Dependency Isolation: Virtual Environments
To avoid dependency leakage and the infamous "works on my machine" syndrome:
python3 -m venv .venv
source .venv/bin/activate # Unix
# .venv\Scripts\activate.bat # Windows CMD
# .venv\Scripts\Activate.ps1 # Windows PowerShell
pip install -r requirements.txt
python3 script.py
Side effect: Forgetting to activate the virtual environment leads to subtle import failures or mismatched package versions.
Argument Passing and Exit Codes
Most production scripts require arguments and signal status with exit codes. Minimal example:
greet.py
:
import sys
if len(sys.argv) != 2:
print("Usage: greet.py <username>", file=sys.stderr)
sys.exit(1)
print(f"Hello, {sys.argv[1]}")
Invocation:
python3 greet.py Alice
Non-zero exit codes communicate failure to supervising processes (cron, systemd, subprocess).
Path Issues and Cross-Directory Invocations
Running scripts in other directories:
python3 /opt/airflow/dags/data_loader.py
If you see:
python3: command not found
add Python to your PATH
, or invoke with an absolute path (/usr/bin/python3
).
Quick One-Liners and Ad-hoc Commands
For diagnostic actions, ephemeral scripting, or configuration checks:
python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
Useful when debugging broken environments, as with missing libssl
:
AttributeError: module 'ssl' has no attribute 'OPENSSL_VERSION'
Execution Summary Table
Scenario | Command | Note |
---|---|---|
Standard script | python3 script.py | Always specify interpreter version |
Shebang + executable | ./script.py | Ensure correct shebang, chmod +x necessary |
Virtual environment execution | source .venv/bin/activate && python script.py | Project-local dependencies |
With CLI arguments | python3 greet.py Alice | Use sys.argv to process input |
Inline evaluation | python3 -c 'print("test")' | For one-off commands or scripting |
Practical Note
- System Python risks: On production Linux, avoid modifying system-wide Python packages. Use
venv
,pipx
, Poetry, or containers. Some Linux tools (e.g., yum, apt) depend on the system Python; breaking it can render package management unusable. - Alternatives exist:
pipenv run
,poetry run
, and Docker-based workflows evict many local configuration issues; these are worth exploring for advanced scenarios.
In summary: Treat the terminal as the definitive environment for Python execution—automate, parameterize, use virtual environments, and always specify your interpreter. Margins for error are slim on production systems; subtle misconfigurations can propagate unnoticed until late-stage failures. Testing these commands in controlled environments prevents “unknown environment” issues in production.
Not perfect, but reliable.