Last active
August 10, 2025 13:27
-
-
Save yeiichi/1f38bb8d124c2d866950eb6eae522ad3 to your computer and use it in GitHub Desktop.
Bash wrapper to run a Python script using a virtual environment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # shellcheck shell=bash | |
| # Bash wrapper to run Python scripts using a virtual environment. | |
| set -Eeuo pipefail | |
| # Constants | |
| readonly HOME_DIR="${HOME}" | |
| readonly VENV_DIR="${HOME_DIR}/path/to/venv" | |
| readonly VENV_BIN="${VENV_DIR}/bin" | |
| readonly ACTIVATE="${VENV_BIN}/activate" | |
| readonly PYTHON_BIN="${VENV_BIN}/python3" | |
| # Default scripts to run when no arguments are provided. | |
| readonly -a SCRIPT_PATHS=( | |
| "${HOME_DIR}/path/to/repo/script_1.py" | |
| "${HOME_DIR}/path/to/repo/script_2.py" | |
| "${HOME_DIR}/path/to/repo/script_3.py" | |
| ) | |
| # Google Cloud related: Explicitly export vars for crontab environment | |
| export GOOGLE_CLOUD_PROJECT="<PROJECT_ID>" | |
| export CREDENTIALS_FILE_PATH="${HOME_DIR}/path/to/<SERVICE_ACCOUNT_KEY>.json" | |
| export GOOGLE_APPLICATION_CREDENTIALS="${HOME_DIR}/path/to/<ADC>.json" | |
| log() { | |
| # Usage: log "message" | |
| printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >&2 | |
| } | |
| die() { | |
| # Usage: die "message" | |
| log "Error: $*" | |
| exit 1 | |
| } | |
| validate_venv() { | |
| [[ -f "${ACTIVATE}" ]] || die "Virtual environment activate script not found at ${ACTIVATE}" | |
| [[ -x "${PYTHON_BIN}" ]] || die "Python interpreter not found/executable at ${PYTHON_BIN}" | |
| } | |
| resolve_scripts() { | |
| # If script paths were passed as arguments, use them; otherwise use defaults. | |
| # Prints resolved list (one per line) to stdout. | |
| if [[ "$#" -gt 0 ]]; then | |
| for s in "$@"; do | |
| printf '%s\n' "$s" | |
| done | |
| else | |
| for s in "${SCRIPT_PATHS[@]}"; do | |
| printf '%s\n' "$s" | |
| done | |
| fi | |
| } | |
| validate_scripts_exist() { | |
| # Usage: validate_scripts_exist <script1> <script2> ... | |
| for script in "$@"; do | |
| [[ -f "${script}" ]] || die "Python script not found at ${script}" | |
| done | |
| } | |
| run_scripts() { | |
| # Usage: run_scripts <script1> <script2> ... | |
| # Prefer executing via the venv's python directly (no need to source), | |
| # which avoids leaking environment changes to the caller. | |
| for script in "$@"; do | |
| log "Running: ${script}" | |
| "${PYTHON_BIN}" "${script}" || die "Failed to execute script ${script}" | |
| done | |
| } | |
| main() { | |
| validate_venv | |
| # Collect scripts from args or default list | |
| mapfile -t scripts < <(resolve_scripts "$@") | |
| validate_scripts_exist "${scripts[@]}" | |
| # Optionally activate if scripts rely on environment hooks; not required for running via PYTHON_BIN. | |
| # shellcheck disable=SC1090 | |
| source "${ACTIVATE}" || die "Failed to activate virtual environment at ${VENV_DIR}" | |
| run_scripts "${scripts[@]}" | |
| log "All scripts completed successfully." | |
| } | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment