Since OS X comes from a unix heritage, you will want to store system files in /usr/local/bin
for command line applications and scripts that belong to the system locally and not to a specific user. You may need to create this directory first by running:
sudo mkdir -p /usr/local/bin
You can move any command line application to that folder by running:
sudo mv my-binary /usr/local/bin/
To make sure that /usr/local/bin
is part of your standard search path in Terminal, check the content of /etc/paths
and add it if necessary:
grep -w /usr/local/bin /etc/paths || sudo sh -c 'echo /usr/local/bin >> /etc/paths'
Some users make a second directory for user level scripts, but this is even more subject to personal preference.
I typically make a bin directory in each user folder and then hide it from Finder - but you can make that decision yourself whether you want it hidden:
mkdir ~/bin
chflags hidden ~/bin
In this case, you'll want to have each user's path include this location by modifying the shell startup scripts (~/.bash_profile
for bash which is the standard shell)
export PATH=$PATH:~/bin
or by hard coding the path to each app when you run it.
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
Best Answer
Use Automator.
Where it says
(* Your script goes here *)
, replace that text with the following code: