67

I'd like to script the installation of the Xcode Command Line Tools.

On Mavericks,

xcode-select --install

will open a dialog prompting the user to install, but I'd like to trigger the install without the dialog, like using the softwareupdate command.

Is there a way to do this?

Edit:

Specifically, xcode-select --install launches an application that downloads and installs the tools without requiring the user to manually download them or have an Apple Developer account. It appears to use /System/Library/CoreServices/Install Command Line Developer Tools.app to do this.

I would like to use the same mechanism that Apple is, but without the GUI. I do not want to have to manually download the .dmg containing the tools as this seems fragile. Apple provides several other command-line tools, like softwareupdate and install that download or install software directly from Apple, and I'm looking to find the same for this type of distribution.

2
  • 1
    Are you trying to do this for an internal script or for some kind of distribution? The reason I ask is because the developer tools require a (free) developer account to access and distributing them outside of that would violate Apple's licensing agreement.
    – Colin C.
    Oct 28, 2013 at 17:40
  • 1
    @ColinC. xcode-select --install does not require an Apple Developer account. It may require the acceptance of the license agreement before the tools are used, but it downloads them without an account.
    – also
    Oct 28, 2013 at 20:25

8 Answers 8

47

Wish I could claim credit for this one, but I found it buried in https://github.com/chcokr/osx-init/blob/master/install.sh

This worked on my 10.10 headless VM without a logged in UI. Updates applied for compatibility with at least 10.9-10.14

touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress;
PROD=$(softwareupdate -l |
  grep "\*.*Command Line" |
  head -n 1 | awk -F"*" '{print $2}' |
  sed -e 's/^ *//' |
  tr -d '\n')
softwareupdate -i "$PROD" --verbose
rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress

This presumes you only have 1 result to softwareupdate -l | grep "\*.*Command Line" - if this returns multiple versions, you might need more specific logic. (I dont have a repro case)

one variation that seems to work (limited testing) on 10.10-10.14 (10.9 doesn't return an osx version number in the cli tools name..so this doesn't work there):

PROD=$(softwareupdate -l |
 grep "\*.*Command Line.*$(sw_vers -productVersion|awk -F. '{print $1"."$2}')" |
 head -n 1 | awk -F"*" '{print $2}' |
 sed -e 's/^ *//' |
 tr -d '\n')

a few example results:

* Command Line Tools (OS X Mavericks)-6.2
* Command Line Tools (OS X 10.10) for Xcode-7.2
* Command Line Tools (macOS El Capitan version 10.11) for Xcode-8.2
* Command Line Tools (macOS High Sierra version 10.13) for Xcode-10.1
* Command Line Tools (macOS Mojave version 10.14) for Xcode-10.1
4
  • There is an extra step for prompting sudo password. How to remove that?
    – rosshjb
    Aug 13, 2020 at 18:00
  • 3
    For Catalina, the command needs to be slightly tweaked softwareupdate -l | grep "*.*Command Line" | tail -n 1 | awk -F"*" '{print $2}' | sed -e 's/^ *//' | sed 's/Label: //g' | tr -d '\n'
    – SenG
    Aug 24, 2020 at 23:19
  • 1
    @jinbeomhong, you could apply the setuid bit on the script (chmod u+s <scriptname>), and then you wouldn't have to enter sudo password. This can be a security risk if anyone else has access to your computer, so caveat emptor.
    – Br.Bill
    Apr 13, 2021 at 0:06
  • 1
    This does not seem to work on Ventura as the list is empty for me when running softwareupdate -l. Did anyone solve this for Ventura?
    – lony
    Jul 25 at 19:45
21
  1. Download the Command Line Tools package from the Apple Developer site.

  2. Mount the downloaded1 DMG:

    hdiutil attach "command_line_tools_os_x_mountain_lion_for_xcode__october_2013.dmg"
    
  3. Run the installer via the command line:

    cd "/Volumes/Command Line Tools (Mountain Lion)"
    installer -verbose -pkg "Command Line Tools (Mountain Lion).mkpg" -target /
    
  4. When finished, unmount the DMG and delete the download.

    1. Eject the DMG2.

      cd /
      hdiutil detach /dev/disk3s2
      
    2. Delete the DMG.

      rm "command_line_tools_os_x_mountain_lion_for_xcode__october_2013.dmg"
      

1 At the time of writing, the downloaded DMG and package name is accurate, however in the future, the name may change. Remember to alter the command (or use tab-completion) to fill in the relevant portion of the command.
2 If the command does not work, check the disk matches the name of the mount (as per mount).

3
  • 1
    I would like this to be future proof, and I don't want to have to provide my own copy of the tools disk image. xcode-select --install downloads and installs the tools for the user, and it doesn't require an ADC . I want to do exactly this, but without the GUI.
    – also
    Oct 28, 2013 at 20:32
  • 1
    Found points 1 and 2 very useful for installing the Hardware IO Tools. Jan 15, 2016 at 2:50
  • If you're using this for any serious (non-personal) reason, you should be hosting your own artifacts anyway. You'd still want to populate your artifact repository in an automated way, but if your goal is reproducible builds you are going to need to install the same package versions each time from a known safe location
    – Brandon
    Oct 2 at 5:06
12

An attempt to clean up the accepted answer's style and logic, making it as version-independent as possible, using softwareupdate to its full capacity and introducing a re-usable os variable:

#!/bin/bash
# Requires root
os=$(sw_vers -productVersion | awk -F. '{print $1 "." $2}')
if softwareupdate --history | grep --silent "Command Line Tools.*${os}"; then
    echo 'Command-line tools already installed.' 
else
    echo 'Installing Command-line tools...'
    in_progress=/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
    touch ${in_progress}
    product=$(softwareupdate --list | awk "/\* Command Line.*${os}/ { sub(/^   \* /, \"\"); print }")
    softwareupdate --verbose --install "${product}" || echo 'Installation failed.' 1>&2 && rm ${in_progress} && exit 1
    rm ${in_progress}
    echo 'Installation succeeded.'
fi
2
  • just a note: the sw_vers filter doesnt work on various releases before 10.10. (I can't speak to 10.11-10.13, only tested today on 10.9 10.10 and 10.14) (see my updated answer for some examples)
    – keen
    Jan 22, 2019 at 16:34
  • 2
    This presumes that the XCode command line tools version is the same as the macOS version, and, at least on my system (macOS 12.4, XCode client tools 13.4) that is not the case. Jul 20, 2022 at 17:45
7

An alternative is to use this applescript I wrote:

https://gist.github.com/brysgo/9007731

do shell script "xcode-select --install"
do shell script "sleep 1"

tell application "System Events"
    tell process "Install Command Line Developer Tools"
        keystroke return
        click button "Agree" of window "License Agreement"
    end tell
end tell

xcode-select --install
sleep 1
osascript <<EOD
  tell application "System Events"
    tell process "Install Command Line Developer Tools"
      keystroke return
      click button "Agree" of window "License Agreement"
    end tell
  end tell
EOD
1
  • 1
    macos 10.11 I get the error "osascript is not allowed on assistive access"
    – ClintM
    Nov 10, 2017 at 14:54
6

I found that if you install Home Brew, it will automatically install the command line tools.

I tested this using this vagrant image.

Run the following command to install Homebrew, and in doing so install the Command Line Tools.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  • I know the original question only asked how to install the Command Line Tools, but I don't know any mac these days that doesn't also have Home Brew installed on it.
1
2

This is what I use, partly based on brysgo's answer.

sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db \
    "INSERT or REPLACE INTO access(service,client,client_type,allowed,prompt_count) VALUES('kTCCServiceAccessibility','com.apple.Terminal',0,1,1);"

if [[ "$(xcode-select -p)" == "" ]]; then
  printf "\n### Installing Xcode command line tools\n"
  xcode-select --install
  sleep 2
  osascript <<EOD
    tell application "System Events"
      tell process "Install Command Line Developer Tools"
        click button "Install" of window ""
        click button "Agree" of window "License Agreement"
        repeat until exists button "Done" of window ""
          delay 1
        end repeat
        click button "Done" of window ""
      end tell
    end tell
EOD
fi

update: Apple keeps adding new columns to the access database, you only need to specify values for the first 5, updated the code to reflect this.

2

EDIT (2021-2022): Apple's servers now respond with a 302 Redirect to https://developer.apple.com/unauthorized/

Post-apocalypt... er... post-2021 Solution

This short excerpt from my macOS bootstrap.sh script has been tested as of December 2021.

# Try the AppleScript automation method rather than relying on manual .xip / .dmg download & mirroring
# Note: Apple broke automated Xcode installer downloads.  Now requires manual Apple ID sign-in.
# Source: https://web.archive.org/web/20211210020829/https://techviewleo.com/install-xcode-command-line-tools-macos/
xcode-select --install
sleep 1
osascript <<-EOD
    tell application "System Events"
      tell process "Install Command Line Developer Tools"
        keystroke return
        click button "Agree" of window "License Agreement"
      end tell
    end tell
EOD

Old Solutions (pre-2021)

A couple more alternatives may be found at these answers:

Download XCode Command Line Tools

You can download the XCode 4.x CLTools packages from their official download site via direct links.

Here is a script that will automate the install process for you 1.

EDIT (2021-2022): Apple servers now respond with a 302 Redirect to https://developer.apple.com/unauthorized/ when trying to download the CLT packages. Based on this, Apple broke all unattended direct downloads without logging with an Apple ID first. The number of hoops that a script would need to jump through to login, store cookies, and download is prohibitive.

To find updated links for the tools, you can use this command:

curl -Lks https://devimages.apple.com.edgekey.net/downloads/xcode/simulators/index-3905972D-B609-49CE-8D06-51ADC78E07BC.dvtdownloadableindex | plutil -convert json -o - - | python -mjson.tool | less

EDIT (2021-2022): This URL now appears to have broken SSL certificates, and the latest version available is Xcode.CLTools.10.8 version 2014.4 (command_line_tools_for_osx_mountain_lion_april_2014.dmg)...

Note: The curl command above now has the -k flag added to work around this certificate validation issue. Be aware that the -k / --insecure command line option flag will bypass SSL certificate security checks. This is insecure and there is no way to verify using a PKI + CA chain of trust that this domain is trustworthy and still owned by Apple. It's recommended to use the alternative xcode-select --install + osascript solution above.

[1] Please don't abuse/overload their servers

You may find that it is easier to first Login to the Apple Developer Download Site and download the latest Command Line Tools available there. You can then host the .dmg on your own package repo server and be able to reliably install the .dmg on many machines with hdiutil without having to login to developer.apple.com.

As of 06/10/2015, the link to the latest Command Line Tools dmg is:

http://adcdownload.apple.com/Developer_Tools/Command_Line_Tools_OS_X_10.10_for_Xcode_6.3.2/commandlinetoolsosx10.10forxcode6.3.2.dmg

EDIT (2021-2022): This URL no longer works... Apple's servers now respond with a 302 Redirect to https://developer.apple.com/unauthorized/ if you are not logged in with an Apple ID.

Please see alternative xcode-select --install + osascript solution above.

3
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.
    – grg
    Jun 7, 2015 at 9:21
  • 1
    @grgarside: Took some time to update this script with the latest Yosemite / XCode 6.3.2 CLT dmg, and copied essential parts of the answer locally to this answer.
    – TrinitronX
    Jun 10, 2015 at 17:06
  • @grgarside: I realized the linking issue & that the script was probably out of date, but didn't have time to update it on the same day I initially posted. I just wanted to give those links as a good place to start and as a note to self to go back and update & test things again.
    – TrinitronX
    Jun 10, 2015 at 17:10
1

I had to modify the code slightly for Monterey 12.0.1.

#!/bin/bash
echo "Checking Xcode CLI tools"
# Only run if the tools are not installed yet
# To check that try to print the SDK path
xcode-select -p &> /dev/null
if [ $? -ne 0 ]; then
  echo "Xcode CLI tools not found. Installing them..."
  touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress;
  PROD=$(softwareupdate -l |
    grep "\*.*Command Line" |
    tail -n 1 | sed 's/^[^C]* //')
  softwareupdate -i "$PROD" --verbose;
else
  echo "Xcode CLI tools OK"
fi
1

You must log in to answer this question.

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