Skip to content

AiMLops Project 3.4 Bash Script analysis

Linux88888 edited this page May 5, 2025 · 3 revisions

Bash Script Errors Analysis

Common Bash Script Errors in the MLOps Platform Setup

This document analyzes the errors found in your deployment script and explains the key topics you should understand to fix and prevent similar issues.

βœ… All Errors and Issues in the Script

πŸ”΄ 1. Incorrect set command

set -eoa pipefail

Problem: -eoa is invalid. Likely a typo for -eo pipefail.

Fix:

set -eo pipefail

πŸ”΄ 2. Improper quoting for variables

cp "$SCRIPT_DIR/config.env" $PLATFORM_CONFIG 
source $PLATFORM_CONFIG

Problem: $PLATFORM_CONFIG should be quoted.

Fix:

cp "$SCRIPT_DIR/config.env" "$PLATFORM_CONFIG"
source "$PLATFORM_CONFIG"

πŸ”΄ 3. Unsafe use of read in scripts

read -p "Enter the number of your choice [1-6] (default is [1]): " choice

Problem: If run in a non-interactive environment, read will hang or fail silently.

Fix: Add timeouts or allow non-interactive execution:

read -t 60 -p "Enter the number of your choice [1-6] (default is [1]): " choice || true

πŸ”΄ 4. Appending settings repeatedly

echo -e "\nDEPLOYMENT_OPTION=$DEPLOYMENT_OPTION" >> $PLATFORM_CONFIG

Problem: Repeated runs of the script will keep appending to .config, causing duplicate/conflicting keys.

Fix: Use sed to update or create keys cleanly:

grep -q '^DEPLOYMENT_OPTION=' "$PLATFORM_CONFIG" && \
  sed -i "s|^DEPLOYMENT_OPTION=.*|DEPLOYMENT_OPTION=$DEPLOYMENT_OPTION|" "$PLATFORM_CONFIG" || \
  echo "DEPLOYMENT_OPTION=$DEPLOYMENT_OPTION" >> "$PLATFORM_CONFIG"

πŸ”΄ 5. Platform-dependent disk space check

DISK_SPACE=$(df -k . | awk -F ' ' '{print $4}' | sed -n '2 p')

Problem: This might break on systems with localized or differently formatted df.

Fix: More robust parsing:

DISK_SPACE=$(df -Pk . | awk 'NR==2 {print $4}')

πŸ”΄ 6. Overwrites user-chosen cluster unintentionally

kind delete cluster --name $CLUSTER_NAME

Problem: Could destroy a production cluster by accident if variables are wrong.

Fix: Add confirmation and validation before deletion:

echo "About to delete cluster: $CLUSTER_NAME"
read -p "Are you sure you want to proceed? (y/N): " confirm
if [[ "$confirm" == [yY] ]]; then
  kind delete cluster --name "$CLUSTER_NAME"
else
  echo "Cluster deletion cancelled"
  exit 1
fi

πŸ”΄ 7. Hardcoded kind context

kubectl cluster-info --context kind-$CLUSTER_NAME

Problem: Might fail if the cluster was renamed or created with a different config.

Fix: Consider dynamically determining context:

kubectl config get-contexts -o name | grep "$CLUSTER_NAME" | xargs kubectl cluster-info --context

πŸ”΄ 8. INSTALL_TYPE used without being defined

if [ "$INSTALL_TYPE" = "cloud" ]; then

Problem: INSTALL_TYPE is never set in the script, causing this condition to always fail.

Fix: Either define INSTALL_TYPE from config.env or remove the block.

πŸ”΄ 9. Doesn't cleanup temp file if kubectl apply fails permanently

tmp_file=$(mktemp)
# later rm "$tmp_file"

Problem: rm is only called on success.

Fix: Use trap to clean up:

tmp_file=$(mktemp)
trap 'rm -f "$tmp_file"' EXIT

Topics to Understand for Robust Bash Scripting

1. Bash Variable Quoting and Expansion

  • Why it matters: Unquoted variables can lead to word splitting, empty values causing unexpected behavior, or even command injection.
  • Best practices:
    • Always quote variables in commands: "$VAR" not $VAR
    • Use ${VAR:-default} for variables that might be unset
    • Consider using set -u to catch unset variables

2. Bash Error Handling with set Options

  • Options:
    • set -e: Exit immediately if a command fails
    • set -o pipefail: Fail if any command in a pipe fails
    • set -u: Treat unset variables as errors
    • set -x: Print commands before execution (debugging)
  • Usage: Put set -euo pipefail at the top of your scripts for safer execution

3. File Descriptor and Process Management

  • Understanding:
    • How to properly handle stdin/stdout/stderr
    • Using traps for cleanup
    • Process substitution and subshells
  • Example:
    # Redirect stderr to stdout
    command 2>&1
    
    # Capture output while allowing it to display
    output=$(command | tee /dev/tty)
    
    # Ensure cleanup with trap
    trap 'rm -f "$TMP_FILE"' EXIT

4. Configuration Management Best Practices

  • Approaches:
    • Use grep/sed to update config files instead of appending
    • Consider using a proper key-value parser/editor
    • Use namespaces in config files to avoid collisions
  • Example:
    # Update or add a key
    update_config() {
      local key="$1"
      local value="$2"
      local file="$3"
      if grep -q "^$key=" "$file"; then
        sed -i "s|^$key=.*|$key=$value|" "$file"
      else
        echo "$key=$value" >> "$file"
      fi
    }

5. Safe User Input Handling

  • Principles:
    • Always validate user input
    • Provide timeouts for interactive prompts
    • Have non-interactive fallbacks
  • Example:
    # Safe input with validation, timeout, and default
    get_user_choice() {
      local prompt="$1"
      local default="$2"
      local response
      read -t 30 -p "$prompt" response || true
      response=${response:-$default}
      if [[ ! "$response" =~ ^[1-6]$ ]]; then
        echo "$default"
      else
        echo "$response"
      fi
    }

6. Platform Independence

  • Strategies:
    • Test commands for existence before using them
    • Use POSIX-compatible alternatives when possible
    • Document system requirements
  • Example:
    # Check for command existence
    check_command() {
      command -v "$1" >/dev/null 2>&1 || { 
        echo >&2 "Required command '$1' not found. Aborting."; 
        exit 1; 
      }
    }
    
    check_command kubectl

7. Kubernetes and Kind Cluster Management

  • Key concepts:
    • Context-aware operations
    • Safe cluster deletion procedures
    • Proper resource application order
  • Best practices:
    • Always verify cluster name before deletion
    • Use wait conditions for resources to be ready
    • Implement proper retry logic with backoff

Clone this wiki locally