Created
October 27, 2025 20:48
-
-
Save j1cs/1e6dfe5d96e7f8b23ea72d8a88a6a399 to your computer and use it in GitHub Desktop.
Download ISO MacOS
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 | |
| set -Eeuo pipefail | |
| # Colors for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' # No Color | |
| # Functions for printing messages | |
| info() { | |
| echo -e "${BLUE}[INFO]${NC} $1" | |
| } | |
| success() { | |
| echo -e "${GREEN}[SUCCESS]${NC} $1" | |
| } | |
| error() { | |
| echo -e "${RED}[ERROR]${NC} $1" | |
| } | |
| warn() { | |
| echo -e "${YELLOW}[WARN]${NC} $1" | |
| } | |
| # Function to generate random hexadecimal numbers | |
| getRandom() { | |
| local length="$1" | |
| local result="" | |
| local chars=("0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F") | |
| for ((i=0; i<length; i++)); do | |
| result+="${chars[$((RANDOM % 16))]}" | |
| done | |
| echo "$result" | |
| } | |
| # Function to format bytes | |
| formatBytes() { | |
| local bytes="$1" | |
| if [ "$bytes" -lt 1024 ]; then | |
| echo "${bytes}B" | |
| elif [ "$bytes" -lt 1048576 ]; then | |
| echo "$((bytes / 1024))KB" | |
| elif [ "$bytes" -lt 1073741824 ]; then | |
| echo "$((bytes / 1048576))MB" | |
| else | |
| echo "$((bytes / 1073741824))GB" | |
| fi | |
| } | |
| # Main download function | |
| download() { | |
| local dest="$1" | |
| local board="$2" | |
| local version="$3" | |
| local type="latest" | |
| local appleSession="" | |
| local downloadLink="" | |
| local downloadSession="" | |
| local mlb="00000000000000000" | |
| local rc total size | |
| info "Downloading macOS ${version^} recovery image..." | |
| # Get Apple session | |
| info "Connecting to Apple servers..." | |
| appleSession=$(curl --disable -v -H "Host: osrecovery.apple.com" \ | |
| -H "Connection: close" \ | |
| -A "InternetRecovery/1.0" \ | |
| https://osrecovery.apple.com/ 2>&1 | tr ';' '\n' | awk -F'session=|;' '{print $2}' | grep 1) | |
| if [ -z "$appleSession" ]; then | |
| error "Failed to obtain Apple session" | |
| return 1 | |
| fi | |
| # Request download information | |
| info "Fetching download information..." | |
| local info_response | |
| info_response=$(curl --disable -s -X POST \ | |
| -H "Host: osrecovery.apple.com" \ | |
| -H "Connection: close" \ | |
| -A "InternetRecovery/1.0" \ | |
| -b "session=\"${appleSession}\"" \ | |
| -H "Content-Type: text/plain" \ | |
| -d $'cid='"$(getRandom 16)"$'\nsn='"${mlb}"$'\nbid='"${board}"$'\nk='"$(getRandom 64)"$'\nfg='"$(getRandom 64)"$'\nos='"${type}" \ | |
| https://osrecovery.apple.com/InstallationPayload/RecoveryImage | tr ' ' '\n') | |
| downloadLink=$(echo "$info_response" | grep 'oscdn' | grep 'dmg') | |
| downloadSession=$(echo "$info_response" | grep 'expires' | grep 'dmg') | |
| if [ -z "$downloadLink" ] || [ -z "$downloadSession" ]; then | |
| error "Failed to obtain download link" | |
| # Check connectivity | |
| if ! curl --silent --max-time 10 --output /dev/null --fail \ | |
| -H "Host: osrecovery.apple.com" \ | |
| -H "Connection: close" \ | |
| -A "InternetRecovery/1.0" \ | |
| https://osrecovery.apple.com/; then | |
| error "No connection to Apple servers" | |
| fi | |
| return 1 | |
| fi | |
| info "Download link obtained successfully" | |
| info "Downloading file..." | |
| # Download the image | |
| rm -f "$dest" | |
| if wget "$downloadLink" -O "$dest" \ | |
| --header "Host: oscdn.apple.com" \ | |
| --header "Connection: close" \ | |
| --header "User-Agent: InternetRecovery/1.0" \ | |
| --header "Cookie: AssetToken=${downloadSession}" \ | |
| --timeout=30 \ | |
| --no-http-keep-alive \ | |
| --show-progress \ | |
| --progress=bar:force:noscroll; then | |
| if [ -f "$dest" ]; then | |
| total=$(stat -c%s "$dest") | |
| size=$(formatBytes "$total") | |
| if [ "$total" -lt 100000 ]; then | |
| error "Invalid recovery image, file is only $size" | |
| rm -f "$dest" | |
| return 1 | |
| fi | |
| success "Download completed successfully!" | |
| success "File saved at: $dest" | |
| success "Size: $size" | |
| return 0 | |
| fi | |
| fi | |
| error "Download failed" | |
| return 1 | |
| } | |
| # Function to convert DMG to ISO | |
| convert_to_iso() { | |
| local dmg_file="$1" | |
| local iso_file="${dmg_file%.dmg}.img" | |
| info "Converting DMG to IMG format..." | |
| if ! command -v dmg2img &> /dev/null; then | |
| warn "dmg2img is not installed. Skipping conversion." | |
| warn "To install: sudo apt-get install dmg2img (Debian/Ubuntu)" | |
| warn " or: sudo yum install dmg2img (RedHat/CentOS)" | |
| return 1 | |
| fi | |
| if dmg2img "$dmg_file" "$iso_file"; then | |
| local total size | |
| total=$(stat -c%s "$iso_file") | |
| size=$(formatBytes "$total") | |
| success "Conversion completed successfully!" | |
| success "IMG file saved at: $iso_file" | |
| success "Size: $size" | |
| return 0 | |
| else | |
| error "Conversion failed" | |
| return 1 | |
| fi | |
| } | |
| # Function to show menu | |
| show_menu() { | |
| echo "" | |
| echo "==========================================" | |
| echo " macOS Recovery Image Downloader" | |
| echo "==========================================" | |
| echo "" | |
| echo "Select the macOS version to download:" | |
| echo "" | |
| echo " 1) Tahoe (macOS 16.x / 26.x)" | |
| echo " 2) Sequoia (macOS 15.x)" | |
| echo " 3) Sonoma (macOS 14.x)" | |
| echo " 4) Ventura (macOS 13.x)" | |
| echo " 5) Monterey (macOS 12.x)" | |
| echo " 6) Big Sur (macOS 11.x)" | |
| echo " 7) Catalina (macOS 10.x)" | |
| echo " 0) Exit" | |
| echo "" | |
| } | |
| # Main function | |
| main() { | |
| local choice | |
| local version | |
| local board | |
| local dest | |
| # Check dependencies | |
| if ! command -v curl &> /dev/null; then | |
| error "curl is not installed. Please install it first." | |
| exit 1 | |
| fi | |
| if ! command -v wget &> /dev/null; then | |
| error "wget is not installed. Please install it first." | |
| exit 1 | |
| fi | |
| show_menu | |
| read -p "Enter your choice [0-7]: " choice | |
| case "$choice" in | |
| 1) | |
| version="Tahoe" | |
| board="Mac-CFF7D910A743CAAF" | |
| ;; | |
| 2) | |
| version="Sequoia" | |
| board="Mac-937A206F2EE63C01" | |
| ;; | |
| 3) | |
| version="Sonoma" | |
| board="Mac-827FAC58A8FDFA22" | |
| ;; | |
| 4) | |
| version="Ventura" | |
| board="Mac-4B682C642B45593E" | |
| ;; | |
| 5) | |
| version="Monterey" | |
| board="Mac-B809C3757DA9BB8D" | |
| ;; | |
| 6) | |
| version="Big Sur" | |
| board="Mac-2BD1B31983FE1663" | |
| ;; | |
| 7) | |
| version="Catalina" | |
| board="Mac-00BE6ED71E35EB86" | |
| ;; | |
| 0) | |
| info "Exiting..." | |
| exit 0 | |
| ;; | |
| *) | |
| error "Invalid option" | |
| exit 1 | |
| ;; | |
| esac | |
| echo "" | |
| info "You selected: macOS $version" | |
| echo "" | |
| # Ask for destination path | |
| read -p "Enter the path to save the file (default: ./macos_${version,,}.dmg): " dest | |
| if [ -z "$dest" ]; then | |
| dest="./macos_${version,,}.dmg" | |
| fi | |
| # Check if file already exists | |
| if [ -f "$dest" ]; then | |
| warn "File $dest already exists" | |
| read -p "Do you want to overwrite it? (y/N): " overwrite | |
| if [[ ! "$overwrite" =~ ^[yY]$ ]]; then | |
| info "Operation cancelled" | |
| exit 0 | |
| fi | |
| fi | |
| echo "" | |
| info "Starting download..." | |
| echo "" | |
| # Perform the download | |
| if download "$dest" "$board" "$version"; then | |
| echo "" | |
| success "Download completed!" | |
| echo "" | |
| # Ask if user wants to convert to IMG | |
| read -p "Do you want to convert the DMG to IMG format for bootable USB? (y/N): " convert_choice | |
| if [[ "$convert_choice" =~ ^[yY]$ ]]; then | |
| echo "" | |
| if convert_to_iso "$dest"; then | |
| echo "" | |
| success "Process completed!" | |
| success "Your macOS $version recovery image is ready" | |
| success "DMG file: $dest" | |
| success "IMG file: ${dest%.dmg}.img" | |
| echo "" | |
| info "To create a bootable USB, use:" | |
| info " sudo dd if=${dest%.dmg}.img of=/dev/sdX bs=4M status=progress" | |
| info " (Replace /dev/sdX with your USB device)" | |
| else | |
| echo "" | |
| warn "Conversion skipped or failed" | |
| success "DMG file is still available at: $dest" | |
| fi | |
| else | |
| success "Your macOS $version recovery image is ready at: $dest" | |
| fi | |
| else | |
| echo "" | |
| error "Download failed. Please try again." | |
| exit 1 | |
| fi | |
| } | |
| # Run the script | |
| main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment