Note
This no longer works with more recent versions of OS X, including 10.10 Yosemite (I'm not sure about 10.9 Mavericks). It does work with 10.8 Mountain Lion, however.
It's actually not too hard, but you do need to have admin privileges (using the sudo
command to write to /etc
).
From Terminal (or your favorite substitute), see if there's anything in the file /etc/launchd.conf
:
cat /etc/launchd.conf
If you get an error like
cat: /etc/launchd.conf: No such file or directory
then continue with the next step. If the cat
command does display some content, copy it.
Determine your system's current path, as we'll need to make sure we include it later:
launchctl getenv PATH
In your favorite editor, create a new text file with the following content, modified to fit your needs:
setenv PATH /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/Users/YourUserName/bin:/path/to/gems/bin
Make sure you've included the entire contents of the path from the previous step, otherwise you'll break your system.
If the cat
command from Step 1 displayed some content, paste it into the new file before the setenv PATH
command. If it already contains a setenv PATH
command, just modify it to add the extra directories you need.
Save the new file in your home directory (/Users/YourUserName
) as launchd.conf
.
Go back to Terminal and enter:
sudo mv ~/launchd.conf /etc
to use admin power to move the new file to /etc
, replacing anything that was there before. Depending on your previous usage of the sudo
command, you may get a short "be careful doing what you're doing" message, but either way you'll need to enter your password. /etc
is not directly accessible through the Save dialog of graphical editors unless you're a real power user and know how to get around OSX's file system restrictions.
Reboot your computer
And you should be all set. If you're interested, launchd
and launchctl
use the csh
/tcsh
syntax, so you can't use the bash
/zsh
export PATH=/usr/local/bin:...
format.
command -pv
uses a "default value for PATH".
$ which ruby
/home/mikel/.rvm/rubies/ruby-1.9.3-p484/bin/ruby
$ command -pv ruby
/usr/bin/ruby
Unfortunately that doesn't work in zsh
, so based on Stephane's comment, we could use getconf PATH
:
$ PATH=$(getconf PATH) which ruby
or use command -v
in place of which
, as recommended in Why not use "which"? What to use then?
$ PATH=$(getconf PATH) command -v ruby
The downside with these approaches is that if the system administrator installed a system-wide version into say /usr/local/bin
or /opt/local/bin
, and all users had that in PATH
(e.g. via /etc/profile
or /etc/environment
or similar), the above probably wouldn't find it.
In your specific case, I'd suggest trying something specific to Ruby. Here's some ideas that might work:
Filter out versions in the user's home directory (and relative paths):
(
IFS=:
set -f
for dir in $PATH; do
case $dir/ in
"$HOME/"*) ;;
/*/)
if [ -f "$dir/ruby" ] && [ -x "$dir/ruby" ]; then
printf '%s\n' "$dir/ruby"
break
fi;;
esac
done
)
Filter out versions in the rvm directory
(
IFS=:
set -f
for dir in $PATH; do
case $dir/ in
"$rvmpath/"*) ;;
/*/)
if [ -f "$dir/ruby" ] && [ -x "$dir/ruby" ]; then
printf '%s\n' "$dir/ruby"
break
fi;;
esac
done
)
Filter out writeable rubies (last resort, assumes not running as root)
(
IFS=:
set -f
for dir in $PATH; do
case $dir/ in
/*/)
ruby=$dir/ruby
if [ -f "$ruby" ] && [ -x "$ruby" ] && [ ! -w "$ruby" ]; then
printf '%s\n' "$ruby"
break
fi;;
esac
done
)
Ask rvm
, chruby
, etc.
(
rvm system
chruby system
command -v ruby
)
The last way makes rvm
select the default Ruby, but we do it in a subshell, so that the user's preferred Ruby is restored afterwards. (chruby
part untested.)
Best Answer
If there is an empty element in
PATH
this refers to'.'
and can be seen as insecure.If the dot or empty element at the end of the
PATH
, this is not highly insecure, since it would only hit if someone places a binary in a directory that uses a misspelled system binary name.For
CDPATH
it is the other way round: it you do not have the dot or empty element,cd
will not find subdirectories in the current directory.The tilde inside a
PATH
string is not understood. This is why the POSIX standard requires to expand tilde sequences after a colon in the command line when a shell macro is assigned.Regarding the text you added to your question after I answered: these tilde characters are expanded before the command is executed.