Last active
June 3, 2026 16:54
-
-
Save luzfcb/4770500adaf392825ff57c904d3444e1 to your computer and use it in GitHub Desktop.
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 | |
| # Exit immediately if any command exits with a non-zero status | |
| # Treat unset variables as an error, and catch errors in pipelined commands | |
| set -euo pipefail | |
| # Initialize options with defaults or environment variables first | |
| # These can be overridden by explicit command-line arguments below. | |
| CACHE_DIR="${ORACLE_CACHE_DIR:-/tmp/oracle}" | |
| INSTALL_DIR="${ORACLE_INSTALL_DIR:-/opt/oracle}" | |
| ORACLE_CLEANUP_UNUSED="${ORACLE_CLEANUP_UNUSED:-false}" | |
| ORACLE_INSTALL_DEBUG="${ORACLE_INSTALL_DEBUG:-false}" | |
| # Debug logger helper | |
| debug_log() { | |
| if [[ "${ORACLE_INSTALL_DEBUG:-false}" == "true" ]]; then | |
| echo "[DEBUG] $1" >&2 | |
| fi | |
| } | |
| show_help() { | |
| cat <<EOF | |
| Oracle Instant Client & SDK Installer | |
| Usage: | |
| $0 -i | --install <version> [options] | |
| $0 -h | --help | |
| Options: | |
| -i, --install VERSION Install Oracle Instant Client. | |
| Supported versions: 19, 21, 23, or latest. | |
| -ul, --update-link Scrape and fetch the latest download URLs directly from the Oracle website. | |
| --light Install the smaller 'Basic Light' package instead of standard Basic. | |
| --sdk Also install the SDK for the specified version. | |
| --jdbc Also install the JDBC supplement for the specified version. | |
| --odbc Also install the ODBC supplement for the specified version. | |
| --plus Also install the SQL*Plus package for the specified version. | |
| --tools Also install the Tools package for the specified version. | |
| -d, --install-dir DIR The target directory for installation (default: /opt/oracle). | |
| -c, --cache-dir DIR The directory used to cache downloads (default: /tmp/oracle). | |
| --cleanup Remove unnecessary files to keep the installation minimal (default: skip). | |
| --debug, -v Enable verbose debug logging and shell trace. | |
| -h, --help Show this help message. | |
| Environment Variables (Fallback if options are not passed): | |
| ORACLE_INSTALL_DIR Same as --install-dir. | |
| ORACLE_CACHE_DIR Same as --cache-dir. | |
| ORACLE_CLEANUP_UNUSED Set to 'true' to enable cleanup (default: false). | |
| ORACLE_INSTALL_DEBUG Set to 'true' to enable debug logging (same as --debug). | |
| Examples: | |
| # Install Version 19 Basic Light client inside \$HOME/oracle with custom cache path | |
| $0 -i 19 --light -d \$HOME/oracle -c /tmp/my_custom_cache | |
| # Install Version 21 Basic client, SDK, and SQL*Plus with lightweight cleanup enabled | |
| $0 --install 21 --sdk --plus --cleanup | |
| # Dynamically pull the latest URLs from Oracle and install the latest Client with SDK and SQL*Plus | |
| $0 -i latest --sdk --plus -ul --debug | |
| EOF | |
| } | |
| # Defaults for command execution | |
| USE_LIGHT="false" | |
| INSTALL_SDK="false" | |
| INSTALL_JDBC="false" | |
| INSTALL_ODBC="false" | |
| INSTALL_PLUS="false" | |
| INSTALL_TOOLS="false" | |
| UPDATE_LINKS="false" | |
| VERSION="" | |
| COMMAND="" | |
| # 1. Parsing arguments | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| -h|--help) | |
| show_help | |
| exit 0 | |
| ;; | |
| -i|--install) | |
| COMMAND="install" | |
| shift | |
| if [[ $# -gt 0 ]]; then | |
| VERSION="$1" | |
| else | |
| echo "Error: '--install' (-i) option requires a version number (19, 21, 23, or latest)." >&2 | |
| show_help | |
| exit 1 | |
| fi | |
| ;; | |
| -ul|--update-link) | |
| UPDATE_LINKS="true" | |
| ;; | |
| --light) | |
| USE_LIGHT="true" | |
| ;; | |
| --sdk) | |
| INSTALL_SDK="true" | |
| ;; | |
| --jdbc) | |
| INSTALL_JDBC="true" | |
| ;; | |
| --odbc) | |
| INSTALL_ODBC="true" | |
| ;; | |
| --plus) | |
| INSTALL_PLUS="true" | |
| ;; | |
| --tools) | |
| INSTALL_TOOLS="true" | |
| ;; | |
| -d|--install-dir) | |
| shift | |
| if [[ $# -gt 0 ]]; then | |
| INSTALL_DIR="$1" | |
| else | |
| echo "Error: --install-dir requires a directory path." >&2 | |
| exit 1 | |
| fi | |
| ;; | |
| -c|--cache-dir) | |
| shift | |
| if [[ $# -gt 0 ]]; then | |
| CACHE_DIR="$1" | |
| else | |
| echo "Error: --cache-dir requires a directory path." >&2 | |
| exit 1 | |
| fi | |
| ;; | |
| --cleanup) | |
| ORACLE_CLEANUP_UNUSED="true" | |
| ;; | |
| -v|--debug) | |
| ORACLE_INSTALL_DEBUG="true" | |
| ;; | |
| *) | |
| # If it's a version number and we haven't set it yet | |
| if [[ -n "$COMMAND" && -z "$VERSION" ]]; then | |
| VERSION="$1" | |
| else | |
| echo "Error: Unknown or misplaced argument '$1'" >&2 | |
| show_help | |
| exit 1 | |
| fi | |
| ;; | |
| esac | |
| shift | |
| done | |
| # Enable shell tracing if debug mode is requested | |
| if [[ "$ORACLE_INSTALL_DEBUG" == "true" ]]; then | |
| set -x | |
| fi | |
| if [[ -z "$COMMAND" ]]; then | |
| echo "Error: No command specified. Please use -i or --install <version>." >&2 | |
| show_help | |
| exit 1 | |
| fi | |
| if [[ "$VERSION" != "19" && "$VERSION" != "21" && "$VERSION" != "23" && "$VERSION" != "latest" ]]; then | |
| echo "Error: Invalid version '$VERSION'. Supported versions are: 19, 21, 23, or latest." >&2 | |
| exit 1 | |
| fi | |
| # 2. Dependency Check | |
| debug_log "Starting dependency check..." | |
| for cmd in unzip wget grep python3; do | |
| if ! command -v "$cmd" &> /dev/null; then | |
| echo "Error: '$cmd' is required but not installed. Please install it first." >&2 | |
| exit 1 | |
| fi | |
| done | |
| debug_log "All required dependencies are installed." | |
| # Save literal user input paths before expansion for raw preservation | |
| RAW_INSTALL_DIR="$INSTALL_DIR" | |
| # Dynamically expand any environment variables (e.g. $HOME, $ORACLE_BASE) or tilde (~) internally | |
| # so that all downstream directory creation and file unzipping operations work seamlessly. | |
| INSTALL_DIR=$(python3 -c "import os, sys; print(os.path.expanduser(os.path.expandvars(sys.argv[1])))" "$INSTALL_DIR") | |
| CACHE_DIR=$(python3 -c "import os, sys; print(os.path.expanduser(os.path.expandvars(sys.argv[1])))" "$CACHE_DIR") | |
| # 3. Define Fallback URLs | |
| V19_BASIC="https://download.oracle.com/otn_software/linux/instantclient/1931000v2/instantclient-basic-linux.x64-19.31.0.0.0dbru.zip" | |
| V19_LIGHT="https://download.oracle.com/otn_software/linux/instantclient/1931000v2/instantclient-basiclite-linux.x64-19.31.0.0.0dbru.zip" | |
| V19_SDK="https://download.oracle.com/otn_software/linux/instantclient/1931000v2/instantclient-sdk-linux.x64-19.31.0.0.0dbru.zip" | |
| V19_JDBC="https://download.oracle.com/otn_software/linux/instantclient/1931000v2/instantclient-jdbc-linux.x64-19.31.0.0.0dbru.zip" | |
| V19_ODBC="https://download.oracle.com/otn_software/linux/instantclient/1931000v2/instantclient-odbc-linux.x64-19.31.0.0.0dbru.zip" | |
| V19_PLUS="https://download.oracle.com/otn_software/linux/instantclient/1931000v2/instantclient-sqlplus-linux.x64-19.31.0.0.0dbru.zip" | |
| V19_TOOLS="https://download.oracle.com/otn_software/linux/instantclient/1931000v2/instantclient-tools-linux.x64-19.31.0.0.0dbru.zip" | |
| V21_BASIC="https://download.oracle.com/otn_software/linux/instantclient/2121000/instantclient-basic-linux.x64-21.21.0.0.0dbru.zip" | |
| V21_LIGHT="https://download.oracle.com/otn_software/linux/instantclient/2121000/instantclient-basiclite-linux.x64-21.21.0.0.0dbru.zip" | |
| V21_SDK="https://download.oracle.com/otn_software/linux/instantclient/2121000/instantclient-sdk-linux.x64-21.21.0.0.0dbru.zip" | |
| V21_JDBC="https://download.oracle.com/otn_software/linux/instantclient/2121000/instantclient-jdbc-linux.x64-21.21.0.0.0dbru.zip" | |
| V21_ODBC="https://download.oracle.com/otn_software/linux/instantclient/2121000/instantclient-odbc-linux.x64-21.21.0.0.0dbru.zip" | |
| V21_PLUS="https://download.oracle.com/otn_software/linux/instantclient/2121000/instantclient-sqlplus-linux.x64-21.21.0.0.0dbru.zip" | |
| V21_TOOLS="https://download.oracle.com/otn_software/linux/instantclient/2121000/instantclient-tools-linux.x64-21.21.0.0.0dbru.zip" | |
| V23_BASIC="https://download.oracle.com/otn_software/linux/instantclient/2326200/instantclient-basic-linux.x64-23.26.2.0.0.zip" | |
| V23_LIGHT="https://download.oracle.com/otn_software/linux/instantclient/2326200/instantclient-basiclite-linux.x64-23.26.2.0.0.zip" | |
| V23_SDK="https://download.oracle.com/otn_software/linux/instantclient/2326200/instantclient-sdk-linux.x64-23.26.2.0.0.zip" | |
| V23_JDBC="https://download.oracle.com/otn_software/linux/instantclient/2326200/instantclient-jdbc-linux.x64-23.26.2.0.0.zip" | |
| V23_ODBC="https://download.oracle.com/otn_software/linux/instantclient/2326200/instantclient-odbc-linux.x64-23.26.2.0.0.zip" | |
| V23_PLUS="https://download.oracle.com/otn_software/linux/instantclient/2326200/instantclient-sqlplus-linux.x64-23.26.2.0.0.zip" | |
| V23_TOOLS="https://download.oracle.com/otn_software/linux/instantclient/2326200/instantclient-tools-linux.x64-23.26.2.0.0.zip" | |
| # Resolve fallback static URLs based on version selection | |
| ORACLE_BASIC_URL="" | |
| ORACLE_SDK_URL="" | |
| ORACLE_JDBC_URL="" | |
| ORACLE_ODBC_URL="" | |
| ORACLE_PLUS_URL="" | |
| ORACLE_TOOLS_URL="" | |
| case "$VERSION" in | |
| 19) | |
| ORACLE_BASIC_URL=$( [[ "$USE_LIGHT" == "true" ]] && echo "$V19_LIGHT" || echo "$V19_BASIC" ) | |
| ORACLE_SDK_URL="$V19_SDK" | |
| ORACLE_JDBC_URL="$V19_JDBC" | |
| ORACLE_ODBC_URL="$V19_ODBC" | |
| ORACLE_PLUS_URL="$V19_PLUS" | |
| ORACLE_TOOLS_URL="$V19_TOOLS" | |
| ;; | |
| 21) | |
| ORACLE_BASIC_URL=$( [[ "$USE_LIGHT" == "true" ]] && echo "$V21_LIGHT" || echo "$V21_BASIC" ) | |
| ORACLE_SDK_URL="$V21_SDK" | |
| ORACLE_JDBC_URL="$V21_JDBC" | |
| ORACLE_ODBC_URL="$V21_ODBC" | |
| ORACLE_PLUS_URL="$V21_PLUS" | |
| ORACLE_TOOLS_URL="$V21_TOOLS" | |
| ;; | |
| 23|latest) | |
| ORACLE_BASIC_URL=$( [[ "$USE_LIGHT" == "true" ]] && echo "$V23_LIGHT" || echo "$V23_BASIC" ) | |
| ORACLE_SDK_URL="$V23_SDK" | |
| ORACLE_JDBC_URL="$V23_JDBC" | |
| ORACLE_ODBC_URL="$V23_ODBC" | |
| ORACLE_PLUS_URL="$V23_PLUS" | |
| ORACLE_TOOLS_URL="$V23_TOOLS" | |
| ;; | |
| esac | |
| # 4. Optional Live Scraper (triggered by --update-link / -ul) | |
| if [[ "$UPDATE_LINKS" == "true" ]]; then | |
| echo "Scraping and fetching the latest download links directly from Oracle..." | |
| SCRAPED_JSON=$(python3 -c " | |
| import re, urllib.request, json, sys | |
| try: | |
| url = 'https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html' | |
| req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) | |
| with urllib.request.urlopen(req) as response: | |
| html = response.read().decode('utf-8') | |
| except Exception as e: | |
| sys.exit(1) | |
| links = re.findall(r'//download\.oracle\.com/otn_software/linux/instantclient/[^\s\'\">]+\.zip', html) | |
| pkg_map = { | |
| 'basiclite': 'light', | |
| 'basic': 'basic', | |
| 'sdk': 'sdk', | |
| 'jdbc': 'jdbc', | |
| 'odbc': 'odbc', | |
| 'sqlplus': 'plus', | |
| 'tools': 'tools' | |
| } | |
| def get_pkg_type(link): | |
| name = link.split('/')[-1] | |
| if 'basiclite' in name: | |
| return 'light' | |
| for k, v in pkg_map.items(): | |
| if k in name: | |
| return v | |
| return None | |
| def get_major_and_version(link): | |
| name = link.split('/')[-1] | |
| match = re.search(r'-(\d+)\.(\d+)\.(\d+)\.(\d+)', name) | |
| if match: | |
| version_tuple = tuple(int(x) for x in match.groups()) | |
| return version_tuple[0], version_tuple | |
| return None, None | |
| grouped = {} | |
| for link in links: | |
| full_link = link if link.startswith('http') else 'https:' + link | |
| pkg = get_pkg_type(full_link) | |
| if not pkg: | |
| continue | |
| major, ver_tuple = get_major_and_version(full_link) | |
| if not major: | |
| continue | |
| key = (major, pkg) | |
| if key not in grouped or ver_tuple > grouped[key][0]: | |
| grouped[key] = (ver_tuple, full_link) | |
| result = {} | |
| for (major, pkg), (ver, link) in grouped.items(): | |
| s_major = str(major) | |
| if s_major not in result: | |
| result[s_major] = {} | |
| result[s_major][pkg] = link | |
| print(json.dumps(result)) | |
| " 2>/dev/null || echo "") | |
| if [[ -n "$SCRAPED_JSON" ]]; then | |
| TARGET_MAJOR="$VERSION" | |
| if [[ "$VERSION" == "latest" ]]; then | |
| # Dynamically detect the highest major version key in scraped JSON | |
| TARGET_MAJOR=$(python3 -c "import json, sys; d = json.loads(sys.argv[1]); print(max(d.keys(), key=int))" "$SCRAPED_JSON") | |
| debug_log "Scraped highest major version: $TARGET_MAJOR" | |
| fi | |
| # Check if target major exists in scraped data | |
| HAS_VERSION=$(python3 -c "import json, sys; d = json.loads(sys.argv[1]); print('true' if sys.argv[2] in d else 'false')" "$SCRAPED_JSON" "$TARGET_MAJOR") | |
| if [[ "$HAS_VERSION" == "true" ]]; then | |
| echo "Successfully loaded latest live URLs for Version $TARGET_MAJOR!" | |
| ORACLE_BASIC_URL=$(python3 -c "import json, sys; d = json.loads(sys.argv[1]); print(d[sys.argv[2]].get('basic', ''))" "$SCRAPED_JSON" "$TARGET_MAJOR") | |
| ORACLE_SDK_URL=$(python3 -c "import json, sys; d = json.loads(sys.argv[1]); print(d[sys.argv[2]].get('sdk', ''))" "$SCRAPED_JSON" "$TARGET_MAJOR") | |
| ORACLE_JDBC_URL=$(python3 -c "import json, sys; d = json.loads(sys.argv[1]); print(d[sys.argv[2]].get('jdbc', ''))" "$SCRAPED_JSON" "$TARGET_MAJOR") | |
| ORACLE_ODBC_URL=$(python3 -c "import json, sys; d = json.loads(sys.argv[1]); print(d[sys.argv[2]].get('odbc', ''))" "$SCRAPED_JSON" "$TARGET_MAJOR") | |
| ORACLE_PLUS_URL=$(python3 -c "import json, sys; d = json.loads(sys.argv[1]); print(d[sys.argv[2]].get('plus', ''))" "$SCRAPED_JSON" "$TARGET_MAJOR") | |
| ORACLE_TOOLS_URL=$(python3 -c "import json, sys; d = json.loads(sys.argv[1]); print(d[sys.argv[2]].get('tools', ''))" "$SCRAPED_JSON" "$TARGET_MAJOR") | |
| if [[ "$USE_LIGHT" == "true" ]]; then | |
| ORACLE_BASIC_URL=$(python3 -c "import json, sys; d = json.loads(sys.argv[1]); print(d[sys.argv[2]].get('light', ''))" "$SCRAPED_JSON" "$TARGET_MAJOR") | |
| fi | |
| else | |
| echo "Warning: Version $TARGET_MAJOR not found in scraped URLs. Falling back to built-in links." >&2 | |
| fi | |
| else | |
| echo "Warning: Could not connect to Oracle or parse HTML. Falling back to built-in offline links." >&2 | |
| fi | |
| fi | |
| # 5. Define Package Metadata and Settings | |
| declare -A PKG_ENABLED | |
| declare -A PKG_URL | |
| declare -A PKG_ZIP | |
| declare -A PKG_LABEL | |
| PKG_ENABLED[basic]="true" | |
| PKG_ENABLED[sdk]="$INSTALL_SDK" | |
| PKG_ENABLED[jdbc]="$INSTALL_JDBC" | |
| PKG_ENABLED[odbc]="$INSTALL_ODBC" | |
| PKG_ENABLED[plus]="$INSTALL_PLUS" | |
| PKG_ENABLED[tools]="$INSTALL_TOOLS" | |
| PKG_URL[basic]="$ORACLE_BASIC_URL" | |
| PKG_URL[sdk]="$ORACLE_SDK_URL" | |
| PKG_URL[jdbc]="$ORACLE_JDBC_URL" | |
| PKG_URL[odbc]="$ORACLE_ODBC_URL" | |
| PKG_URL[plus]="$ORACLE_PLUS_URL" | |
| PKG_URL[tools]="$ORACLE_TOOLS_URL" | |
| PKG_LABEL[basic]="Base Client" | |
| PKG_LABEL[sdk]="SDK" | |
| PKG_LABEL[jdbc]="JDBC Supplement" | |
| PKG_LABEL[odbc]="ODBC Supplement" | |
| PKG_LABEL[plus]="SQL*Plus" | |
| PKG_LABEL[tools]="Tools" | |
| # Resolve ZIP file paths dynamically based on URLs | |
| for pkg in basic sdk jdbc odbc plus tools; do | |
| if [[ "${PKG_ENABLED[$pkg]}" == "true" ]]; then | |
| url="${PKG_URL[$pkg]}" | |
| file_name="${url##*/}" | |
| PKG_ZIP[$pkg]="$CACHE_DIR/$file_name" | |
| fi | |
| done | |
| # 6. Check Write Permissions and create directories | |
| if ! mkdir -p "$INSTALL_DIR" 2>/dev/null; then | |
| echo "Error: Cannot write to installation directory '$INSTALL_DIR'." >&2 | |
| echo "Please run this script as root/sudo or specify a different path using --install-dir (-d)." >&2 | |
| echo "Example: $0 -i 19 -d \$HOME/oracle" >&2 | |
| exit 1 | |
| fi | |
| mkdir -p "$CACHE_DIR" | |
| # 7. Cache & Download Function | |
| download_if_needed() { | |
| local url="$1" | |
| local dest="$2" | |
| debug_log "Checking integrity of: $dest..." | |
| if ! unzip -tq "$dest" >/dev/null 2>&1; then | |
| debug_log "Package '$dest' is missing or corrupted. Downloading from '$url'..." | |
| rm -f "$dest" | |
| wget --progress=dot:giga --tries 3 --wait 2 --output-document "$dest" "$url" | |
| else | |
| debug_log "Package '$dest' is cached and valid. Skipping download." | |
| fi | |
| } | |
| # Download all enabled packages sequentially | |
| for pkg in basic sdk jdbc odbc plus tools; do | |
| if [[ "${PKG_ENABLED[$pkg]}" == "true" ]]; then | |
| download_if_needed "${PKG_URL[$pkg]}" "${PKG_ZIP[$pkg]}" | |
| fi | |
| done | |
| # 8. Dynamically resolve the exact top-level directory of THIS specific installation version. | |
| # We look specifically for directories starting with 'instantclient' to avoid matching 'META-INF'. | |
| debug_log "Parsing zip file contents to resolve the target subdirectory name..." | |
| RELATIVE_DIR=$(unzip -qql "${PKG_ZIP[basic]}" | grep -oE 'instantclient[^/ ]*/' | head -n 1 | cut -d/ -f1) | |
| debug_log "Resolved RELATIVE_DIR: '$RELATIVE_DIR'" | |
| if [[ -z "$RELATIVE_DIR" ]]; then | |
| echo "Error: Could not dynamically determine the extracted directory name from the zip file." >&2 | |
| exit 1 | |
| fi | |
| TARGET_VERSION_DIR="$INSTALL_DIR/$RELATIVE_DIR" | |
| debug_log "Target installation folder: $TARGET_VERSION_DIR" | |
| # 9. Extract Packages | |
| for pkg in basic sdk jdbc odbc plus tools; do | |
| if [[ "${PKG_ENABLED[$pkg]}" == "true" ]]; then | |
| echo "Extracting ${PKG_LABEL[$pkg]} package specifically to $INSTALL_DIR..." | |
| unzip -o "${PKG_ZIP[$pkg]}" -d "$INSTALL_DIR" -x "META-INF/*" | |
| fi | |
| done | |
| # 10. Clean up unused files ONLY within this specific version folder (if cleanup is enabled) | |
| if [[ "$ORACLE_CLEANUP_UNUSED" == "true" ]]; then | |
| echo "Removing unnecessary files in $TARGET_VERSION_DIR to keep installation minimal..." | |
| debug_log "Cleaning up *jdbc*, *occi*, *mysql*, *README, *jar, uidrvci, genezi, adrci inside $TARGET_VERSION_DIR..." | |
| if ! ( | |
| cd "$TARGET_VERSION_DIR" && \ | |
| rm -f -- *jdbc* *occi* *mysql* *README *jar uidrvci genezi adrci | |
| ); then | |
| echo "Warning: Cleanup of unused files failed inside '$TARGET_VERSION_DIR', skipping cleanup..." >&2 | |
| fi | |
| else | |
| echo "Skipping lightweight cleanup step as ORACLE_CLEANUP_UNUSED is set to '$ORACLE_CLEANUP_UNUSED'." | |
| fi | |
| # 11. Environment configuration prompt | |
| # Get original non-root user if run via sudo | |
| USER_HOME="${HOME}" | |
| BASH_CONFIG_FILE=".bashrc" | |
| if [[ -n "${SUDO_USER:-}" ]]; then | |
| debug_log "Script run via sudo. Resolving original user's home directory..." | |
| USER_HOME=$(getent passwd "$SUDO_USER" | cut -d: -f6) | |
| fi | |
| debug_log "User home resolved to: $USER_HOME" | |
| # Intelligently collapse any absolute environment variable value back to its literal name (e.g. $MY_VAR) | |
| DISPLAY_VERSION_DIR="$TARGET_VERSION_DIR" | |
| # Scenario A: If user passed a literal single-quoted variable (e.g. '$MY_VAR/...') | |
| if [[ "$RAW_INSTALL_DIR" == *"$"* || "$RAW_INSTALL_DIR" == "~"* ]]; then | |
| debug_log "Preserving raw literal variable representation: $RAW_INSTALL_DIR" | |
| DISPLAY_VERSION_DIR="$RAW_INSTALL_DIR/$RELATIVE_DIR" | |
| else | |
| # Scenario B: If shell expanded variable before script execution, | |
| # find the longest matching env variable value and substitute its variable name! | |
| debug_log "Scanning environment variables to find absolute path match..." | |
| while IFS='=' read -r var_name var_value; do | |
| # Skip empty, extremely short (e.g. < 4 chars), or standard noisy keys | |
| if [[ -z "$var_value" || "${#var_value}" -lt 4 || "$var_name" == "_" || "$var_name" == "PWD" || "$var_name" == "OLDPWD" ]]; then | |
| continue | |
| fi | |
| if [[ "$DISPLAY_VERSION_DIR" == "$var_value"* ]]; then | |
| debug_log "Matched path prefix with environment variable '$var_name'." | |
| DISPLAY_VERSION_DIR="\$$var_name${DISPLAY_VERSION_DIR#"$var_value"}" | |
| break | |
| fi | |
| done < <(python3 -c "import os; [print(f'{k}={v}') for k, v in sorted(os.environ.items(), key=lambda x: len(x[1]), reverse=True)]") | |
| fi | |
| echo "=======================================================================" | |
| echo " Oracle Instant Client (${RELATIVE_DIR}) successfully installed!" | |
| echo " Packages included:" | |
| echo " - Base Client: $( [[ "$USE_LIGHT" == "true" ]] && echo "Basic Light" || echo "Basic" )" | |
| echo " - SDK: $( [[ "$INSTALL_SDK" == "true" ]] && echo "Yes" || echo "No" )" | |
| echo " - JDBC: $( [[ "$INSTALL_JDBC" == "true" ]] && echo "Yes" || echo "No" )" | |
| echo " - ODBC: $( [[ "$INSTALL_ODBC" == "true" ]] && echo "Yes" || echo "No" )" | |
| echo " - SQL*Plus: $( [[ "$INSTALL_PLUS" == "true" ]] && echo "Yes" || echo "No" )" | |
| echo " - Tools: $( [[ "$INSTALL_TOOLS" == "true" ]] && echo "Yes" || echo "No" )" | |
| echo "=======================================================================" | |
| echo " Version folder: $TARGET_VERSION_DIR" | |
| echo "-----------------------------------------------------------------------" | |
| echo "" | |
| echo "To configure your environment, append the following lines to your shell" | |
| echo "configuration file (e.g., $USER_HOME/$BASH_CONFIG_FILE):" | |
| echo "" | |
| echo "-----------------------------------------------------------------------" | |
| cat <<EOF | |
| # Oracle Instant Client Configuration (${RELATIVE_DIR}) | |
| export LD_LIBRARY_PATH="$DISPLAY_VERSION_DIR\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}" | |
| export PATH="$DISPLAY_VERSION_DIR\${PATH:+:\$PATH}" | |
| EOF | |
| echo "-----------------------------------------------------------------------" | |
| echo "" | |
| echo "You can append this automatically by running:" | |
| echo "cat << 'EOF' >> $USER_HOME/$BASH_CONFIG_FILE" | |
| echo "" | |
| echo "# Oracle Instant Client Configuration (${RELATIVE_DIR})" | |
| echo "export LD_LIBRARY_PATH=\"$DISPLAY_VERSION_DIR\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}\"" | |
| echo "export PATH=\"$DISPLAY_VERSION_DIR\${PATH:+:\$PATH}\"" | |
| echo "EOF" | |
| echo "" | |
| echo "Then, reload your configuration with: source $USER_HOME/$BASH_CONFIG_FILE" | |
| echo "=======================================================================" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment