88

Does anybody know a terminal command that gives me the model of my Mac?

For example - "MacBook Pro, Retina, 13-inch, Mid 2013" or "MacBook Pro, Late 2009" or "Mac Mini, Early 2010".

That information does not exist in the SystemProfiler (/usr/sbin/system_profiler SPHardwareDataType), but in OS X 10.7 and OS X 10.8 you can see that information when you click "More Info..." in the "About This Mac" window.

0

11 Answers 11

89

You can indirectly get this information from a web page and the curl command. In the past this URL has been taken down and rate limited and put behind some sort of captcha to prevent this use, so you might need to resort to other avenues like https://checkcoverage.apple.com/ in that case.

Depending on if your serial numer is 11 or 12 characters long take the last 3 or 4 characters, respectively, and feed that to the following URL after the ?cc=XXXX part. If your serial number was 12 character and ended in DJWR, you would issue this command:

curl https://support-sp.apple.com/sp/product?cc=DJWR

To get your serial number, use the following command:

system_profiler SPHardwareDataType | awk '/Serial/ {print $4}'

Thus, you could have a complicated command to query the internet if you need a single command:

curl https://support-sp.apple.com/sp/product?cc=$(
  system_profiler SPHardwareDataType \
    | awk '/Serial/ {print $4}' \
    | cut -c 9-
)

and then run the output of that through sed to cut to the key part

curl -s https://support-sp.apple.com/sp/product?cc=$(
  system_profiler SPHardwareDataType \
    | awk '/Serial/ {print $4}' \
    | cut -c 9-
) | sed 's|.*<configCode>\(.*\)</configCode>.*|\1|'

There used to be a private library file with these mappings so you could consult it offline, but I noticed it was gone as of 10.8.3 (and perhaps earlier) so the above trick is the only one I know that works on the current OS without third party libraries.

Some nice third party libararies provide a look up of this:

Note that as of November 2017, Apple has forced the use of https over http for this service.

3
  • I made a slightly-less-quick-and-dirty script to accomplish this in Python, using XML parsers: gist.github.com/zigg/6174270
    – Mattie
    Commented Aug 7, 2013 at 13:59
  • 3
    Similar to using sysctl -n hw.model mentioned below, ioreg -c IOPlatformExpertDevice -d 2 | awk -F\" '/IOPlatformSerialNumber/{print $(NF-1)}' will work faster for getting the serial number.
    – n8felton
    Commented Sep 28, 2016 at 18:30
  • 1
    For Apple Silicon, use the following: /usr/libexec/PlistBuddy -c 'Print :0:product-name' /dev/stdin <<< "$(ioreg -arc IOPlatformDevice -k product-name)" 2> /dev/null | tr -cd '[:print:]'
    – da4
    Commented May 20, 2022 at 15:50
55

You can use the command

system_profiler SPHardwareDataType | grep "Model Identifier"

in Terminal to get the model ID of your machine.
Then you can enter that ID on this site which will list the month and year the particular model was launched.

As mentioned in the comments below, the following command is much faster:

sysctl hw.model
2
  • 6
    system_profiler SPHardwareDataType | grep "Model Identifier" runs much faster than the full profiler, but still doesn't return the marketing name as the OP asked. See my answer for a command that works around the "look up" portion of your answer in a terminal friendly manner.
    – bmike
    Commented Aug 6, 2013 at 11:42
  • 1
    Your answer would be spot on for apple.stackexchange.com/questions/40243/… however ;-)
    – bmike
    Commented Aug 6, 2013 at 11:44
8

On El Capitan and Sierra, there's a plist file in a private framework with a dict of info for each model identifier; that dict includes the marketing name (which has the model year in it). I don't know what OS version that particular file came in with, but it's NOT on Snow Leopard (the only thing I have that's older than El Capitan).

#! /bin/ksh
if [ -f /System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes.plist ]
then
    marketingModel="$(modelid="$(system_profiler SPHardwareDataType 2>/dev/null|awk '/Model Identifier:/ {print $NF}')"
    defaults read /System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes.plist "MacBookPro12,1"|sed -n -e 's/\\//g' -e 's/.*marketingModel = "\(.*\)";/\1/p')"
    echo "${marketingModel}"
else
    echo "can't use offline method to find marketing name on this OS version"
fi

So, you could use that (or other similar tricks for other OS versions after checking the OS version, if you know those tricks, which I don't), and if that wasn't applicable, you could always fall back to the approach that requires Internet access.

This is not exactly the same as what About This Mac shows, which in my case is
MacBook Pro (Retina, 13-inch, Early 2015)
while this shows
13" MacBook Pro with Retina display (Early 2015)
but in human-readable terms, I think it's close enough.

2
  • I realize this answer is over 2 years old, but it's gotten the model identifier hardcoded (line 4, MacBookPro12,1) which means it always claims you're on an early 2015 13" mbp.
    – egid
    Commented Dec 14, 2018 at 20:52
  • 2
    Another way: /usr/libexec/PlistBuddy -c "print :$(sysctl hw.model | cut -f 2 -d ' '):_LOCALIZABLE_:marketingModel" /System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes.plist
    – gregmac
    Commented Oct 2, 2019 at 23:09
7

Late to the game, but here's one approach:

hardware_model () {

  local hardware_mod=$(defaults read \
  ~/Library/Preferences/com.apple.SystemProfiler.plist 'CPU Names' \
  |cut -sd '"' -f 4 \
  |uniq)
}

.

This function reads a .plist file and looks for CPU Names within that file:

{
    "CPU Names" =     {
        "J1GN-en-US_US" = "iMac (Retina 5K, 27-inch, 2017)";
    };
} 

, then using the delimiter " parses out the fourth field:

iMac (Retina 5K, 27-inch, 2017) 

Tested to work on the currently supported versions of OS X.

Note that this might return more than one row if the hardware was upgraded:

{
    "JHD4-en-DE_DE" = "MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports)";
    "ML7M-en-DE_DE" = "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)";
}

Adding tail -n 1 after uniq solves this at least for this case.

1
  • This is the simplest approach that actually worked for me on Catalina. The other answers with more votes require internet access or return the Model Identifier, which is misleading. For example, "MacBookPro15,1" corresponds to 2018 and 2019 MBP's. I'd simplify it even further, just with: defaults read ~/Library/Preferences/com.apple.SystemProfiler.plist 'CPU Names' | cut -sd '"' -f 4 | uniq
    – Kamal
    Commented Oct 18, 2019 at 11:02
6

Here is a one liner using PlistBuddy, without any grep, sed or awk-wardness.

/usr/libexec/PlistBuddy -c "print :$(sysctl -n hw.model):_LOCALIZABLE_:marketingModel" /System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes.plist

this returns something like:

15" MacBook Pro with Thunderbolt 3 and Touch ID (Mid 2017)

-

Another one liner that yields a slightly different string, also using PlistBuddy (with a tiny bit of awk):

/usr/libexec/PlistBuddy -c "print :'CPU Names':$(system_profiler SPHardwareDataType | awk '/Serial/ {print $4}' | cut -c 9-)-en-US_US" ~/Library/Preferences/com.apple.SystemProfiler.plist

MacBook Pro (15-inch, 2017)

Credit to several of the above answers for this.

2
  • 2
    In your first snippet, this: English.lproj is now: en.lproj in newer versions of macOS. One could deal with this by prefacing the command with: shopt -s extglob, and then catching for either possibility: @(English|en).lproj .
    – marshki
    Commented Jun 13, 2020 at 10:52
  • 1
    Returns Entry, ":MacBookPro18,1:_LOCALIZABLE_:marketingModel", Does Not Exist on my MBP M1.
    – not2savvy
    Commented Jul 27, 2022 at 19:07
5

We have some 2019 MBPs that return different year models for the two one-liners posted by tabrindle.

His first one-liner (using sysctl -n hw.model) returns 2018 for a 2019 model:

Wrong: 15" MacBook Pro with Thunderbolt 3 and Touch ID (Mid 2018)

But his second one-liner (using system_profiler SPHardwareDataType) returns the correct name:

Right: MacBook Pro (15-inch, 2019)

3

Combining Saaru's answer with a debugged version of Richard Hamilton's I get the following, which works 10.6 thru 10.12 (though the sample size on 10.6 is just one machine) and possibly earlier/later, and does not depend on a connection to the internet and Apple's servers not changing

ATTRIBSFILE=/System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes
if ! [ -f "${ATTRIBSFILE}.plist" ] ; then
  # 10.7 or 10.6
  ATTRIBSFILE=/System/Library/PrivateFrameworks/ServerKit.framework/Versions/A/Resources/English.lproj/XSMachineAttributes
fi
if [ -f "${ATTRIBSFILE}.plist" ]
then
    modelid="$(sysctl -n hw.model)"
    marketingModel="$(defaults read "${ATTRIBSFILE}" "${modelid}" |sed -n -e 's/\\//g' -e 's/.*marketingModel = "\(.*\)";/\1/p')"
    echo "${marketingModel}"
else
    echo "can't use offline method to find marketing name on this OS version"
fi

Some notes on what I discovered to get here:

  • We have to strip ".plist" off the domain for defaults to work in 10.6, and therefore re-add it manually to the shell -f tests
  • the -n flag to sysctl means it prints only the value, saving us some sed or awk work
2

My one line.

curl -s https://support-sp.apple.com/sp/product?cc=$( ioreg -l | grep IOPlatformSerialNumber | awk '{print $4}' | sed 's|"||g' | cut -b9-13 ) | sed "s@.*<configCode>\(.*\)</configCode>.*@\1@"

Output:

MacBook Pro (15-inch, Late 2011)

0
2

The older answers using the online method (sp-support.apple.com) no longer work with Apple's randomized serial number format. So 2021 Macs with M1, M1 Pro and M1 Max. I've created a new method that uses hardware identifiers and data scraped from Apple's Support site to get the marketing name.

See here: https://github.com/quacktacular/mac-device-id-to-model

Usage:

# Determine the model and year:
DEIVCE_IDENTIFIER=$(sysctl hw.model | awk '{print $NF}')
DEVICE_MODEL_CURL=$(curl -s "https://raw.githubusercontent.com/quacktacular/mac-device-id-to-model/main/models.txt" | grep "$DEIVCE_IDENTIFIER")
if [[ $DEVICE_MODEL_CURL = *"("*")"* ]]; then
  DEVICE_MODEL=$( echo $DEVICE_MODEL_CURL | cut -f1 -d"|" ) 
  DEVICE_YEAR=$( echo "$DEVICE_MODEL" | grep -o -E '[0-9][0-9][0-9][0-9]' )
else
  DEVICE_MODEL="Unknown Mac"
  DEVICE_YEAR="N/A"
fi

# Now you can use the variables:
echo $DEVICE_MODEL
echo $DEVICE_YEAR
2

Collect Year From Mac Marketing Model Name https://community.jamf.com/t5/jamf-pro/collect-year-from-mac-marketing-model-name/td-p/250495

#!/bin/bash

# variables

crntusr="$(/usr/bin/stat -f %Su /dev/console)"
ioprdnm="$(/usr/sbin/ioreg -ar -d1 -k product-name)"
srlnmbr="$(/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/awk '/Serial/{print substr($NF,9)}')"
valarch="$(/usr/bin/uname -m)"
valbrnd="$(/usr/sbin/sysctl -n machdep.cpu.brand_string)"
valoahd="$(/usr/bin/pgrep -ail oahd)"
plistsp="/Users/$crntusr/Library/Preferences/com.apple.SystemProfiler.plist"


# if the cpu is Apple Silicon collect the Marketing Model string from ioreg
# if the cpu is Intel collect the Marketing Model string from com.apple.SystemProfiler.plist
# if com.apple.SystemProfiler.plist does not exist create it then collect the string

if [ "$valarch" = 'arm64' ] || [ -n "$valoahd" ] || ! echo "$valbrnd" | /usr/bin/grep -q 'Intel'
then
    mrktmdl=($(/usr/libexec/PlistBuddy -c 'print 0:product-name' /dev/stdin <<< "$ioprdnm"))
elif [ -e "$plistsp" ]
then
    mrktmdl=($(/usr/libexec/PlistBuddy -c "print 'CPU Names':$srlnmbr-en-US_US" "$plistsp"))
else
    /usr/bin/open '/System/Library/CoreServices/Applications/About This Mac.app'; /bin/sleep 2
    /usr/bin/pkill -ail 'System Information'; /bin/sleep 2
    /usr/bin/killall cfprefsd; /bin/sleep 2
    mrktmdl=($(/usr/libexec/PlistBuddy -c "print 'CPU Names':$srlnmbr-en-US_US" "$plistsp"))
fi
/bin/sleep 1


# if none of those methods work collect the Model Identifier, exit

if [ -z "${mrktmdl[*]}" ] || echo "${mrktmdl[*]}" | /usr/bin/grep "File Doesn't Exist"
then
    echo "<result>$(/usr/sbin/sysctl -n hw.model)</result>"
    exit
fi


# parse the string as a space-separated array to match year with regex

for i in "${mrktmdl[@]}"
do
    if echo "$i" | /usr/bin/grep -Eq '^[2][0-9]{3}'
    then
        mdlyear="$(echo "$i" | /usr/bin/sed 's/ //g;s/,//g;s/;//g;s/"//g;s/)//g;s/(//g')"
        break
    fi
done


# compare year collected to year set as "too old"

if [ "$mdlyear" -lt "$(($(/bin/date +%Y)-7))" ]
then
    result="$mdlyear"
fi
echo "<result>${result:-no}</result>"
1
  • 1
    When you are referring to some other material on the internet with a link, it is better to put down explicitly and in as much detail as necessary in your answer the solution suggested in that material. This would prevent your answer from becoming much less helpful should the link you referred to is broken.
    – Alper
    Commented Dec 23, 2021 at 2:59
-7

This should do it:

system_profiler | more
sw_vers
scutil --get ComputerName
sw_vers | awk -F':\t' '{print $2}' | paste -d ' ' - - -
sysctl -n hw.memsize | awk '{print $0/1073741824" GB RAM"}'
sysctl -n machdep.cpu.brand_string
1
  • 3
    None of the commands you've listed do what the question asker asks. Commented Aug 6, 2013 at 10:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .