23

On my Mac I used bash a lot. For my environment settings I added /usr/bin and /usr/local/bin into $PATH as I normally did.

While I do know what /usr/bin and /usr/local/bin are about, I am curious which should go before another, by convention? And is there a specific reason for that?

Similar is for /usr/lib and /usr/local/lib -- hopefully the answer is the same or similar.

a bit more -- Just an extension of the original question, how would you order the following in $PATH following the convention and why?

/bin
/sbin
/usr/bin
/usr/sbin
/usr/local/bin
/usr/local/sbin
/opt/local/bin
/opt/local/sbin
Bruce
  • 1,608
  • 2
  • 17
  • 29
  • See also [this related question](http://unix.stackexchange.com/questions/8656/usr-bin-vs-usr-local-bin-on-linux). – e0k Jan 25 '16 at 04:21

1 Answers1

61

/usr/bin is where binaries supplied by the OS go. /usr/local/bin is where user supplied binaries go. When you type the name of a command on the command line, the shell searches for said command in the paths contained in the $PATH environment variable in order. A common pattern is to have /usr/local/bin precede /usr/bin in $PATH. This allows you to install alternate versions of binaries and have them gracefully "override" the binaries provided by the OS. And OS updates won't clobber your user installed packages. This pattern is notably used in OSX by the popular Homebrew package manager tool.

For instance, at the time of this writing, OSX El Capitan supplies git version 2.5.4 (in /usr/bin). If you want a newer version, you can use Homebrew to install git version 2.7.0 (into /usr/local/bin). Since /usr/local/bin comes before /usr/bin in the $PATH environment variable, when you issue the command git in a shell, the newer Homebrew version will be used.

On fresh new Mac running OSX El Capitan (I happen to have one), the /etc/paths file contains the following:

/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

which produces the following $PATH environment variable:

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

which is compatible with homebrew. I recommend sticking with this OSX default. If you really want to include /usr/local/sbin (listed in your question above), I would put it just before /usr/sbin for similar reasons to above. As for /opt/local/bin and /opt/local/sbin, I haven't personally found the need to add them to the path but it seems they might go in a similar spot as their /usr/local analogs, since /opt traditionally contains user installed binaries.

Note: The same explanation applies to /usr/lib vs. /usr/local/lib.

Asaph
  • 159,146
  • 25
  • 197
  • 199
  • 2
    I'm confused. When I do `cat /etc/paths` I get: `/usr/local/bin`,`/usr/bin`,etc. However, when I `echo $PATH` I get: `/usr/bin:/bin/:`, etc. which is a different order completely. (I should mention this is on Yosemite 10.10) – skube Nov 14 '16 at 13:26
  • 1
    @skube Check if there is a `$PATH` environment variable override in your user's `~/.bash_profile`. If so, comment it out or delete it. – Asaph Nov 14 '16 at 16:49
  • Be aware if you change the rights of the `/usr/local/bin` folder to *writeable* for the *user*, then user apps can just replace sudo with a fake sudo at `/usr/local/bin/sudo` if you have `/usr/local/bin/` higher than `/usr/bin/` in `PATH`. – Binarian Mar 05 '19 at 09:32
  • 2
    @Binarian A user app can simply add an alias to your .bashrc to achieve the same effect. No, putting /usr/loca/bin after /usr/bin cannot protect you from running a malicious sudo. – Yongwei Wu Jun 22 '20 at 14:46
  • 1
    @YongweiWu Thanks for the input. Yes you are right. You described another attack vector, which can make the protection irrelevant if not protected against changing configuration files. What I said is still correct, even if it only accounts for one attack vector. – Binarian Jun 22 '20 at 14:55