How To Run Python In Linux

How To Run Python In Linux

Reading time1 min
#Python#Linux#Programming#pyenv#venv#Docker

Mastering Python Execution on Linux: Terminal, Isolation, and Automation

Efficient Python usage on Linux underpins everything from CI pipelines to production services. Let’s move past basic script execution: version control, environment isolation, and containerization are table stakes for maintainable Python deployments.


1. Quick Validation: Confirm System Python

First, verify your base state. On a typical Ubuntu 20.04 or RHEL 9 system:

python3 --version

Expected output:

Python 3.8.10

If you receive command not found, the interpreter isn't present—install it using the system package manager. Don’t mix package manager installations (apt, yum) with manual downloads unless you’re managing isolated versions.

Ubuntu/Debian:

sudo apt update
sudo apt install python3 python3-pip

RHEL/Fedora:

sudo dnf install python3 python3-pip

2. Script Execution and Shebang Usage

Suppose a file, hello.py, contains:

print("Ready to automate on Linux.")

The standard runtime is:

python3 hello.py

For CI tasks or production scripts, make execution explicit with a shebang:

#!/usr/bin/env python3
print("Run as an executable.")

Then:

chmod +x hello.py
./hello.py

Note: The explicit shebang ensures compatibility in PATH-variant environments (e.g., Jenkins agents).


3. Managing Multiple Python Versions with Pyenv

Complex deployments (legacy projects, library testing) demand multiple Python interpreters. Installing them side-by-side using system packages leads to package manager conflicts and broken dependencies.

pyenv addresses this. It isolates user-level Python installations without requiring sudo.

Install pyenv

Assuming a default bash shell (tested on Ubuntu 22.04):

curl https://pyenv.run | bash

Update your shell config (~/.bashrc or ~/.zshrc):

export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv virtualenv-init -)"

Apply changes:

exec $SHELL

Check installation:

pyenv --version  # e.g., pyenv 2.3.20

Manage Versions

List:

pyenv install --list | grep "^  3\."

Install specifics (reproducibility matters for CI):

pyenv install 3.9.13
pyenv install 3.10.4

Set global or project defaults:

pyenv global 3.10.4
pyenv local 3.9.13  # writes .python-version

Known issue: Some Linux distributions (notably Alpine) may require additional build dependencies:

sudo apt install -y build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python3-openssl git

Expect compilation times for custom versions.


4. Project Isolation with venv (and Gotchas)

Python’s built-in venv module avoids dependency collisions. Within your project directory:

python3 -m venv venv
source venv/bin/activate
pip install requests==2.31.0

Now pip list returns only local dependencies. To exit:

deactivate

Gotcha: Some IDEs (PyCharm, VS Code) auto-detect and may activate different interpreters. Always validate:

which python

Tip: Never commit venv/ to source control; add to .gitignore:

venv/

5. Going Beyond pip: Poetry and Pipx for Modern Workflow

Large projects outgrow ad-hoc dependency installation. Lock files and reproducibility become critical, especially in collaborative or CI/CD setups.

Poetry

Install Poetry (independent from project Python installs):

curl -sSL https://install.python-poetry.org | python3 -

Initialize a new project:

poetry new fastapi-demo
cd fastapi-demo
poetry add fastapi==0.92.0

Run within the Poetry-managed environment:

poetry run python main.py

Poetry maintains a strict poetry.lock for deterministic builds—essential for production parity. Some devs prefer pipenv or hatch as alternatives, but Poetry currently offers one of the best trade-offs for reproducibility versus ease.

pipx

Use pipx for globally isolated command-line tools:

python3 -m pip install --user pipx
pipx install httpie
http GET example.org

No clutter in global site-packages; clean removals too.


6. Containerization: Running Python Apps in Predictable Environments

When absolute reproducibility is needed (dev-prod parity, test automation, hybrid cloud), containers standardize OS libraries, Python, app code, and dependencies.

Minimal Dockerfile (Python 3.10, tested with Docker 24.0+):

FROM python:3.10-slim
WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .

CMD ["python", "main.py"]

Build and test:

docker build -t myapp:0.1 .
docker run --rm myapp:0.1

Note: Containerized python eliminates “but it works on my system” headaches, but for tight resource nodes, -slim images may require extra packages (for musl, cryptography, or pandas workloads).


7. Reference Workflow Table

TaskRecommended ToolingKey Command
Check system Python versionSystem Pythonpython3 --version
Manage multiple interpreterspyenvpyenv install 3.10.4
Project-local dependency isolationvenv/Poetrypython3 -m venv venv, poetry add flask
Scripted environment consistencyDockerdocker build && docker run ...
Dependency/lock management for production CIPoetrypoetry lock, poetry install
CLI tool isolation (global, without polluting system)pipxpipx install black

Additional Notes and Tips

  • Avoid sudo pip install. It breaks system package management and can cause opaque runtime errors:
    ImportError: cannot import name 'sysconfig' from 'distutils'
    
  • For automatic environment activation, consider direnv—fast context switching without sourcing manually.
  • On systems where both Homebrew and apt are active (e.g., WSL), clarify your PATH to avoid interpreter surprises.
  • When building Docker images for ML workloads, favor base images with pinned CUDA versions (e.g., python:3.10.4-cuda11.7) and watch out for native dependency mismatches.
  • Cleaning up unused pyenv versions:
    pyenv uninstall 3.9.13
    
  • To debug import errors in complex deployments, run with PYTHONPATH set explicitly or activate with env -i.

Effective Python execution on Linux hinges not just on the script itself, but on environment curation, version pinning, and automation discipline. Skipping these practices leads to troubleshooting rabbit holes—dependency hell is always one misstep away.

Consider reviewing your own build scripts and Dockerfiles for these practices. Perfection is elusive—sometimes the “system python” is the path of least resistance for a quick task, but for anything long-lived or production-bound, isolation is non-negotiable.

Keep your environments explicit, your dependencies locked, and your deploys repeatable.


For more in-depth workflow examples and edge-case solutions, watch this space or reach out for scenario-specific guidance.