#!/usr/bin/env bash set -euo pipefail # Usage on offline machine: # sudo ./install-offline.sh /path/to/bundle-node-v22.x.y-linux-x64 # # Optional: # INSTALL_PREFIX=/opt/nodejs sudo ./install-offline.sh /path/to/bundle BUNDLE_DIR="${1:-}" INSTALL_PREFIX="${INSTALL_PREFIX:-/opt/nodejs}" if [[ -z "${BUNDLE_DIR}" ]]; then echo "Usage: sudo ./install-offline.sh /path/to/bundle-node-v22.x.y-linux-{x64|arm64}" exit 1 fi if [[ ! -d "${BUNDLE_DIR}" ]]; then echo "Bundle directory not found: ${BUNDLE_DIR}" exit 1 fi if [[ ! -f "${BUNDLE_DIR}/INSTALL_ARGS.txt" ]]; then echo "Missing INSTALL_ARGS.txt in bundle." exit 1 fi # shellcheck disable=SC1091 source "${BUNDLE_DIR}/INSTALL_ARGS.txt" if [[ -z "${ARCHIVE:-}" || -z "${VERSION:-}" ]]; then echo "INSTALL_ARGS.txt is invalid." exit 1 fi if [[ ! -f "${BUNDLE_DIR}/${ARCHIVE}" ]]; then echo "Archive not found: ${BUNDLE_DIR}/${ARCHIVE}" exit 1 fi if [[ ! -f "${BUNDLE_DIR}/SHASUMS256.txt" ]]; then echo "SHASUMS256.txt not found in bundle." exit 1 fi echo "Verifying checksum..." ( cd "${BUNDLE_DIR}" sha256sum -c SHASUMS256.txt --ignore-missing | awk "/${ARCHIVE}: OK/" ) echo "Installing to ${INSTALL_PREFIX}..." sudo mkdir -p "${INSTALL_PREFIX}" sudo tar -xJf "${BUNDLE_DIR}/${ARCHIVE}" -C "${INSTALL_PREFIX}" sudo ln -sfn "${INSTALL_PREFIX}/node-v${VERSION}-linux-${ARCH}" "${INSTALL_PREFIX}/current" PROFILE_FILE="/etc/profile.d/nodejs.sh" LINE='export PATH=/opt/nodejs/current/bin:$PATH' if [[ "${INSTALL_PREFIX}" != "/opt/nodejs" ]]; then LINE="export PATH=${INSTALL_PREFIX}/current/bin:\$PATH" fi echo "Writing ${PROFILE_FILE}..." echo "${LINE}" | sudo tee "${PROFILE_FILE}" >/dev/null sudo chmod 0644 "${PROFILE_FILE}" echo echo "Done. Re-login or run:" echo " source ${PROFILE_FILE}" echo "Check:" echo " node -v" echo " npm -v"