Best way to check in bash if Command Line Tools are installed?
Using bash, I want to check if Command Line Tools are installed.
Currently they are and when I type xcode-select --install
I get:
xcode-select: error: command line tools are already installed, use "Software Update" to install updates It appears Homebrew is already installed. If your intent is to reinstall you should do... blah blah blah
Basically my problem is that I have several methods to check in bash (using if / fi
) but I don't know which solution is the best one.
1) I can do xcode-select -p
and that returns the path /Library/Developer/CommandLineTools
but then how I should build the if
statement? I don't know what will be presented when CLT are not installed.
2) I can do xcode-select --version
. Should I then grep
for a phrase version
since I get
xcode-select version 2343.
3) I can do which xcode-select
but again, in all cases I'm not sure how the if
should look like. I also think that grep
is not the best way, since in the future the output may be different in future version of OSX.
To sum up I would like something like
#!/bin/bash
if [ no idea ]; then
#installed, nothing to do...
else
xcode-select --install
fi
Thanks for any suggestions.
Solution 1:
if type xcode-select >&- && xpath=$( xcode-select --print-path ) &&
test -d "${xpath}" && test -x "${xpath}" ; then
#... is correctly installed
else
#... isn't correctly installed
fi
Strangely, the --print-path
isn't documented in old Xcode versions but is working as -print-path
. On the other hand, the -p
option doesn't
have this compatibility.
Solution 2:
Just because code-select returns a valid path doesn't mean the command line tools are installed:
$ xcode-select -p
/Applications/Xcode.app/Contents/Developer
$ if type xcode-select >&- && xpath=$( xcode-select --print-path ) &&
test -d "${xpath}" && test -x "${xpath}" ; then echo "installed" ; fi
installed
$ xcode-select --install
xcode-select: note: install requested for command line developer tools
Thus, a more accurate check is to use xcode-select to try and install the CLT with the following:
if xcode-select --install 2>&1 | grep installed; then
echo installed;
else
echo not installed, installing;
fi
If it's not installed, it will prompt for installation as your example shows, but without a separate line for the xcode-select --install
.
Solution 3:
Yet another approach would be to use pkgutil
if pkgutil --pkg-info com.apple.pkg.CLTools_Executables >/dev/null 2>&1
then printf '%s\n' "CHECKING INSTALLATION"
count=0
pkgutil --files com.apple.pkg.CLTools_Executables |
while IFS= read file
do
test -e "/${file}" &&
printf '%s\n' "/${file}…OK" ||
{ printf '%s\n' "/${file}…MISSING"; ((count++)); }
done
if (( count > 0 ))
then printf '%s\n' "Command Line Tools are not installed properly"
# Provide instructions to remove and the CommandLineTools directory
# and the package receipt then install instructions
else printf '%s\n' "Command Line Tools are installed"
fi
else printf '%s\n' "Command Line Tools are not installed"
# Provide instructions to install the Command Line Tools
fi