Skip to content

Instantly share code, notes, and snippets.

@ChristopherA
Last active February 2, 2024 05:15
Show Gist options
  • Save ChristopherA/9bce58cb5e3d547458a022858a519bde to your computer and use it in GitHub Desktop.
Save ChristopherA/9bce58cb5e3d547458a022858a519bde to your computer and use it in GitHub Desktop.
macOS Environment Tests
#!/usr/bin/env bash
#===========================================================================
# * INFO
#
# macOS Environment Tests - ./macOS_environment_tests.sh
#
# Scripts to test getting various Apple Macintosh hardware & software
# environment details, setting variables to those values, and some
# useful examples of how to use those variables.
# By Christopher Allen @ChristopherA https://github.com/christophera/
# As a convenience for testing, you can execute this script remotely,
# which will display the results of this test using `curl`. This test
# which does not change any setting nor leave itself on your system. Just
# paste the following command into the Terminal (`⌘␣Terminal`):
# curl -L https://gist.githubusercontent.com/ChristopherA/9bce58cb5e3d547458a022858a519bde/raw/macOS_environment_tests.sh | bash
# ! WARNING: Be cautious whenever someone asks you to run a script that has
# ! `curl` command in it, because if the author is malicious they can corrupt
# ! your system or make it vulnerable. In this case the script is run from a
# ! trusted website (`gist.githubusercontent.com/`), and is from my account
# ! (`ChristopherA`). Make sure you look at the script the URL refers to and
# ! confirm the URL is the same as you pasted into the Terminal, before hitting
# ! return!
#===========================================================================
# TODO: This script has not be tested on all mac operating systems and hardware
# variations. So far:
# * [x] macOS 14: Sonoma (Sunburst)
# * [x] macOS 13: Ventura (Rome)
# * [x] macOS 12: Monterey (Star)
# * [x] macOS 11: Big Sur (GoldenGate)
# * [x] macOS 10.15: Catalina (Jazz)
# * [ ] macOS 10.14: Mojave (Liberty)
# * [ ] macOS 10.13: High Sierra (Lobo)
# * [ ] macOS 10.12: Sierra (Fuji)
# * [ ] OS X 10.11: El Capitan (Gala)
# * [ ] OS X 10.10: Yosemite (Syrah)
# * [ ] OS X 10.9 Mavericks (Cabernet)
# * [ ] OS X 10.8 Mountain Lion (Zinfandel)
# * [ ] OS X 10.7 Lion (Barolo)
# * [ ] OS X 10.6 Snow Leopard
# * [ ] OS X 10.5 Leopard (Chablis)
# * [ ] OS X 10.4.4 Tiger (Intel: Chardonay)
# * [ ] OS X 10.4 Tiger (Merlot)
# * [ ] OS X 10.3 Panther (Pinot)
# * [ ] OS X 10.2: Jaguar
# * [ ] OS X 10.1: Puma
# * [ ] OS X 10.0: Cheetah
# * [ ] OS X 10 beta: Kodiak
#===========================================================================
printf "\nHARDWARE:\n"
# This script is for Mac hardware & software only. Abort if not.
if [ "$(uname -s)" != "Darwin" ]; then
printf "This script is only for Macintosh Hardware & Software! EXIT!"
exit 1
else
osx_is_mac=true
fi
# Which version of macOS are we executing under?
read osx_product_version osx_vers_major osx_vers_minor osx_vers_patch \
<<<$(sw_vers -productVersion | awk -F. '{print $0 " " $1 " " $2 " " $3}')
# Which build of macOS?
osx_build_version="$(sw_vers -buildVersion)"
# What is the human-readable codename for this macOS?
case "$osx_product_version" in
"10.4"*) osx_codename="Mac OS X Tiger" ;;
"10.5"*) osx_codename="Mac OS X Leopard" ;;
"10.6"*) osx_codename="Mac OS X Snow Leopard" ;;
"10.7"*) osx_codename="Mac OS X Lion" ;;
"10.8"*) osx_codename="OS X Mountain Lion" ;;
"10.9"*) osx_codename="OS X Mavericks" ;;
"10.10"*) osx_codename="OS X Yosemite" ;;
"10.11"*) osx_codename="OS X El Capitan" ;;
"10.12"*) osx_codename="macOS Sierra" ;;
"10.13"*) osx_codename="macOS High Sierra" ;;
"10.14"*) osx_codename="macOS Mojave" ;;
"10.15"*) osx_codename="macOS Catalina" ;;
"11."*) osx_codename="macOS Big Sur" ;;
"12."*) osx_codename="macOS Monterey" ;;
"13."*) osx_codename="macOS Ventura" ;;
"14."*) osx_codename="macOS Sonoma" ;;
*) osx_codename="macOS unknown" ;;
esac
osx_distro="$osx_codename $osx_product_version ($osx_build_version)"
# Mac Hardware Model
osx_hardware_model=$(sysctl -n hw.model)
# Get Model Name
Device_Model_Name=$(system_profiler SPHardwareDataType | awk -F ': ' '/Model Name/ { print $2 }')
# Set osx_hardware_model with the actual hardware model of the system
osx_hardware_model=$(sysctl -n hw.model)
# Initialize osx_hardware_model_name
osx_hardware_model_name="(unknown model)"
# Use a case statement to map osx_hardware_model to osx_hardware_model_name
case "$osx_hardware_model" in
"Macmini6,1"|"Macmini6,2")
osx_hardware_model_name="Mac mini, 2012"
;;
"Macmini7,1")
osx_hardware_model_name="Mac mini, 2014"
;;
"Macmini8,1")
osx_hardware_model_name="Mac mini, 2018"
;;
"Macmini9,1")
osx_hardware_model_name="Mac mini (M1), 2020"
;;
"Mac14,3")
osx_hardware_model_name="Mac mini (M2), 2023"
;;
"Mac14,12")
osx_hardware_model_name="Mac mini (M2 Pro), 2023"
;;
"Mac13,1")
osx_hardware_model_name="Mac Studio (M1 Max), 2022"
;;
"Mac13,2")
osx_hardware_model_name="Mac Studio (M1 Ultra), 2022"
;;
"Mac14,13")
osx_hardware_model_name="Mac Studio (M2 Max), 2023"
;;
"Mac14,14")
osx_hardware_model_name="Mac Studio (M2 Ultra), 2023"
;;
# Add more cases here for each model
"MacBookPro18,4")
osx_hardware_model_name="MacBook Pro 14 (M1 Max), 2021"
;;
# Example for a model not listed in your initial snippet
"MacBookAir10,1")
osx_hardware_model_name="MacBook Air 13\" (M1), 2020"
;;
*)
osx_hardware_model_name="Unknown Model"
;;
esac
# VM detection. For instance we can abort if not running inside a VM.
if [ ! -z "$(echo $osx_hardware_model | grep VMware)" ] || [ ! -z "$(echo $osx_hardware_model | grep VirtualMac)" ]; then
osx_hardware_model_is_vm=true
# else
# printf "This macOS is NOT running inside a virtual machine. ABORT\n"
# exit 1
fi
# Example uses:
if [[ "$osx_hardware_model_is_vm" ]]; then
printf "Device: \t\t$Device_Model_Name\t\tsystem_profiler\t⚠️\n"
else
printf "Device:\n\t$osx_distro inside of $osx_hardware_model_name.\t✅\n"
# exit 1 # or we can abort if not vmw
fi
# Print device/model details
if [ -z "$Device_Model_Name" ]; then
script_exit "ERROR: Unable to get Device Model Name!\n" 1
else
printf "Device Model Number:\t$osx_hardware_model\t\t\tsysctl\t\t✅\n"
fi
# Use the osx_hardware_model_name variable as needed
echo "Model Name: $osx_hardware_model"
# Get hardware serial number
Device_Serial_Number=$(/usr/sbin/ioreg -l | awk '/IOPlatformSerialNumber/ { split($0, line, "\""); printf("%s\n", line[4]); }')
if [ -z "$Device_Serial_Number" ]; then
script_exit "ERROR: Unable to get Device Serial Number!\n" 1
else
printf "Device Serial Number:\t$Device_Serial_Number\t\t\tioreg\t\t✅\n"
fi
# Get cpu
Device_CPU=$(/usr/sbin/sysctl -n machdep.cpu.brand_string | sed s/"Apple "//)
if [ -z "$Device_CPU" ]; then
script_exit "ERROR: Unable to get Device Serial Number!\n" 1
else
printf "Device CPU:\t\t$Device_CPU\t\tsysctl\t\t✅\n"
fi
printf "\nmacOS:\n"
# Display version examples:
printf "macOS Product Version:\t$osx_product_version\n"
printf "macOS Major Version:\t$osx_vers_major\n"
printf "macOS Minor Version:\t$osx_vers_minor\n"
printf "macOS Patch Version:\t$osx_vers_patch\n"
printf "macOS Build Version:\t$osx_build_version\n"
printf "macOS Distribution:\t$osx_distro\n"
# Example semver output, e.g. 10.12.6+16G29
osx_semver="$osx_vers_major.$osx_vers_minor.$osx_vers_patch+$osx_build_version"
printf "macOS Semantic Version:\t$osx_semver\n"
printf "\nSOFTWARE:\n"
# Get Safari Version
read osx_safari_version osx_safari_version_major osx_safari_version_minor osx_safari_version_patch \
<<<$(/usr/libexec/PlistBuddy -c "print :CFBundleShortVersionString" \
/Applications/Safari.app/Contents/Info.plist |
awk -F. '{print $0 " " $1 " " $2 " " $3}')
# Display version examples:
printf "Safari Version: $osx_safari_version\n"
printf "Safari Major Version: $osx_safari_version_major\n"
printf "Safari Minor Version: $osx_safari_version_minor\n"
printf "Safari Minor Version: $osx_safari_version_patch\n"
# Example uses:
if [[ "$osx_safari_version_major" -ge 15 ]]; then
printf "\t• Safari Tab Spaces are supported.\n"
else
printf "\t• Older version of Safari, Tab Spaces not supported.\n"
# exit 1 # or we can abort if no support
fi
# You can use these variables in script logic to run different commands based on
# the version of macOS. This gives slightly more granular control down to the
# patch or build version.
if [[ ${os_vers_minor} -ge 11 ]]; then
#DMG_FORMAT=ULFO
printf "\t• The DMG format used by this $osx_distro \n\t distribution is ULFO.\n"
elif [[ ${os_vers_minor} -ge 4 ]]; then
#DMG_FORMAT=UDBZ
printf "\t• The DMG format used by this $osx_distro \n\t distribution is UDBZ.\n"
else
#DMG_FORMAT=UDZO
printf "\t• The DMG format used by this $osx_distro \n\t distributon is UDZO.\n"
fi
printf "\nLOCAL CONFIGURATION:\n"
Current_User=$(/usr/bin/stat -f "%Su" /dev/console)
if [ -z "$Current_User" ]; then
script_exit "ERROR: Unable to get Currently Logged In User!\n" 1
else
printf "Current User:\t\t$Current_User\t\t\t\tstat\t\t✅\n"
fi
# Get human-friendly Computer Nume from SCUTIL
# Attempt to capture the output of the command
SCUTIL_Computer_Name=$(scutil --get ComputerName 2>&1)
# Check if the command was successful
if [ $? -eq 0 ]; then
# Command was successful, print the Computer Name
printf "Computer Name:\t\t$SCUTIL_Computer_Name\t\tscutil\t\t✅\n"
else
# Command failed, handle the error (the error stored in SCUTIL_Computer_Name)
printf "Computer Name:\t\t(not set)\tscutil\t\t\t⚠️\n"
fi
# Get ssh HostName from SCUTIL
# Run command, capturing stdout and stderr into variables
SCUTIL_Host_Name=$(scutil --get HostName 2>&1)
# Check if the command was successful
if [ $? -eq 0 ]; then
# Command was successful, print the Host Name
printf "Host Name:\t\t$SCUTIL_Host_Name\t\tscutil\t\t\t✅\n"
else
# Command failed, handle the error (the error is stored in SCUTIL_Host_Name)
printf "Host Name:\t\t(not set)\t\t\tscutil\t\t⚠️\n"
fi
# Get Bonjour Local Host Name from SCUTIL
# Run command, capturing stdout and stderr into variables
SCUTIL_Local_Host_Name=$(scutil --get LocalHostName 2>&1)
# Check if the command was successful
if [ $? -eq 0 ]; then
# Command was successful, print the Local Host Name
printf "Local Host Name:\t$SCUTIL_Local_Host_Name.local\tscutil\t\t✅\n"
else
# Command failed, handle the error (the error stored in SCUTIL_Local_Host_Name)
printf "Local Host Name:\t(not set)\tscutil\t\t⚠️\n"
fi
@ChristopherA
Copy link
Author

This has now been updated for macOS Ventura 13.0, as of commit #ab8dbcc352b44985af4bd6a7daea7321597adea3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment