7

Contrary to the Linuxes I used, in FreeBSD the /usr/local directory is heavily populated by a normal installation, even without using any ports. In fact, non-basic shells (Bash and Z-Shell) are put there (in /usr/local/bin).

Under Linux it was nice to have custom-built scripts or software in the /usr/local tree for them to be clearly separated from the distribution software (e.g. to easily “deactivate” these “modifications”, by taking /usr/local out of the $PATH).

What is the reasoning behind this? And since I doubt that there is a way to make FreeBSD behave like Linux, what would be the best practices to install custom-build software and files accessible for all users?

viuser
  • 2,614
  • 3
    "there is a way to make FreeBSD behave like Linux" If you want on OS which behaves like Linux, use Linux! FreeBSD isn't Linux. There are similarities but are many differences. If you want to use FreeBSD as FreeBSD (not as Linux) please know it. I think it's a valuable OS, it's worth to learn its idea. – uzsolt Dec 26 '16 at 08:58
  • 2
    @uzsolt stop putting words in my mouth – viuser Dec 26 '16 at 10:34
  • Sorry, I didn't want offensive. Peace and merry Xmas :) – uzsolt Dec 26 '16 at 13:26
  • 1
    My search to get away from Debian's systemd has me looking at alternatives and I must say I too think that it is nicer (and semantically more correct) for /usr/local to mean just my own stuff. NetBSD got it right and installs into /usr/pkg, /usr/pkg/etc - see: https://www.netbsd.org/docs/pkgsrc/using.html – Daniel Sokolowski Oct 24 '18 at 14:40

4 Answers4

11

Under Linux it was nice to have custom-built scripts or software in the /usr/local tree for them to be clearly separated from the distribution software

And that is exactly what you are getting on FreeBSD. Shells like the Z shell and the Bourne Again shell are not part of FreeBSD. They are third-party additions. The operating system is sometimes referred to by the slang name "base". In the BSD world in general, third party additions on top of "base" do not live in /usr. They live in /usr/local.

In the BSD world — and this is true of other BSD operating systems like OpenBSD — you get the operating itself in / and /usr, and the stuff that isn't the operating system in /usr/local. If one wants just the operating system functionality without the additions, one takes /usr/local out of consideration in what one is doing.

The slight twist to this is that FreeBSD derivatives like TrueOS Server and TrueOS Desktop modestly consider their additions on top of FreeBSD to be not part of the operating system. So there's a whole load of TrueOS out-of-the-box stuff that lives in /usr/local with the non-operating-system stuff. For example: It's where you'll find PCDM, the TrueOS display manager, living.

Conversely, /usr/local is where all custom-built softwares that are not parts of the operating system go.

To show how strong this division is:

  • The Mewburn rc scripts for non-operating-system stuff go in /usr/local/etc/rc.d/ and do not get added to /etc/rc.d/. It's where you'll find /usr/local/etc/rc.d/nginx.
  • Non-operating-system configuration files go in /usr/local/etc/ not /etc/. It's where you'll find /usr/local/etc/cups.
  • There's a distinction between /usr/share/man where the operating system manuals are and /usr/local/man where the non-operating-system manuals are.

Even the package manager itself is (currently) not part of the operating system proper. There's a "bootstrap" package manager, pkg-static. This installs pkg, the actual package manager that has configuration files in /usr/local/etc/pkg and that is itself an add-on.

The conceptual leap that you have to make in coming from the Linux "distributions" world is that you don't get an operating system built by selecting from a mish-mash of packages supplied by a "distributor". You get a full operating system as one coherent unit (installed by an installer, upgraded with freebsd-update, and maintained as a single "boot environment" using ZFS), and all of the third-party stuff as ports and packages separate from that. If you yourself are supplying third-party stuff, be you a developer or a system administrator, then you do ports and packages too, or you just put it directly in /usr/local somehow.

On the other hand, custom-built softwares that are parts of the operating system go in / and /usr where the operating system lives. The source and build system for the entire operating system come supplied in /usr/src as part of this one self-sufficient system. You make local modifications there, share them with other people using Subversion (FreeBSD) and git (TrueOS) if you want, and rebuild either the "userland" alone or the entire operating system (both "shell" and "kernel") from that.

Interesting side note

If you nonetheless make your own structure for your own machines, you are, according to the operating system manual itself, expected to provide a local hier manual page superseding the operating system one. ☺

Further reading

JdeBP
  • 68,745
  • 3
    Unlike the ports tree for other BSDs, NetBSD's pkgsrc installs packages into /usr/pkg/ by default, leaving /usr/local/ untouched. – oals Dec 26 '16 at 15:17
  • 2
    “that is exactly what you are getting on FreeBSD”. No, not at all. On most Linux distributions, third-party packages go under /etc and /usr, and /usr/local is only for things that don't come with a package manager. *BSD mix third-party packages with local installations, whereas Linux mix third-party packages with the base OS. – Gilles 'SO- stop being evil' Dec 26 '16 at 22:13
  • You are basing that upon one interpretation of what "the distribution software" is. The whole idea of "distributions" does not apply to the BSDs, so one has to pick an equivalency. The equivalency here is "the distribution software" equals the software that is published along with or as FreeBSD, as (say) softwares that "are included in the official Debian distribution" (Debian's own words) are published alongside or as Debian Linux. As such, the clear separation is there. The conceptual leap, explicitly pointed out, is in changing one's idea of what is being clearly separated. – JdeBP Dec 27 '16 at 10:45
  • What would be a natural deviation from the standard hierarchy? I'd like to use /usr/local/$HOST for custom-built local software that is not installed by pkg or via ports. – viuser Dec 28 '16 at 09:28
  • 2
    @Gilles No, BSDs do not mix 3rd-party software with local software, the local admin does. The admin is responsible for local installs, and is thus able to install local software in, e.g., /opt or /sw, or wherever is convenient. The admin is also able to move 3rd-party installations wherever they want and use /usr/local for local software. This is easy since base system functionality is not dependent on 3rd-party packages. – Kusalananda Dec 31 '16 at 08:55
  • It doesn't make much sense for me for software packages provided by FreeBSD to be considered 3rd party, and our definitions of "full operating system" are not the same. Sounds like I'm getting a rather unsupported OS, that loathsomely requires me to track the original developers of each package to determine where they will install and the mish-mash of who will provide support (vs Red Hat supports all packages). Also, having so much stuff scattered between / and /usr/local is anything but coherent. – jbo5112 Dec 28 '19 at 05:05
4

On FreeBSD Installation PREFIX is set to /usr/local as default. This is used for files installed from packages (and packages have been built by ports of course). Since zsh and bash are packages and are not in base, they go to /usr/local.

You can install your own software to /usr/local, too. Just take care and avoid collisions.

If you want some different destination, create one and install everything custom under a new PREFIX. Some people use /opt. When you want to serve binaries under this PREFIX, you can use the user classes in login.conf(5) and set the path entry there for them to contain something like /opt/bin (read also about cap_mkdb(1) and the user login​ class specification in passwd(5)).

3

/usr/local is (from the man page), the home of all local executables, files, etc. What they mean by "local" is that the software or systems are not specific to the operation of the OS, and generally this indicates that the software in question was built via the port system, or installed by the package manager. For example, both bash, and zsh are provided optionally and must be added on after a bare installation, and so they live there.

By observing a strict hierarchy of OS-specific and other software, automation of OS updates and patches is easier to manage. In this way it's not much different than using the directory to distinguish custom-built scripts and customizations. What you may be missing though, is that the port system on FreeBSD is much broader in scope — it is how you customize your BSD system, not simply a collection of optional software.

Best practice would be to avoid installing untested software for all users which doesn't exist yet in the ports tree. If it's proprietary, it should be installed in /usr/local/. If it's not, why not make a port of your own?

GAD3R
  • 66,769
Ryder
  • 284
1

Part of the confusion over /usr/local comes from the destinction applied to both usr and local (ie. their context).

On Linux, this is implied to be "anything the users have built, and made available globally" (ie. local is "machine", usr is "globally accesible by Users").

On BSD, this is implied to be "anything built that is not part of the base (BSD) OS" (ie. local is "not OS", usr is "extensions to fundamental OS").

I suspect that the main reason 99.9% of build scirpts (./configure and Makefile) default to /usr/local is to cater to Unix "out of the box", and Linux just adopted this (even if its implied context is somewhat different). On BSD this default is forced to /usr/local for anything not considered part of the "base OS".

Remembering that usr is arbitrary in its origins (it could easily have been something else), due to a "drives" size constraints of the time, and the need for a seperate volume in order to accomodate more. EG. even /sbin was on a seperate volume at one point in time, when 5 Megabyte "drives" were the largest available, and the rest of / was pushing those same limits (excluding /usr) .

Having read K&R origins of usr(*), I would say they always built final versions of software that did not specifically pertain to either the OS or its Available Services, as "local" software (in /usr/local - and was probably another volume at one point). And that BSD adopted its "context" due to the increasing amount of software, and a philosophical need to maintain a distinction between / OS, /usr OS Extensions, and /usr/local Non-OS software.

(*) (a citation/url would be useful here).


FWIW on Debian buster the confusion is amplified:

lrwxrwxrwx 1 root root 7 Jan 12  2021 /bin -> usr/bin
lrwxrwxrwx 1 root root 7 Jan 12  2021 /lib -> usr/lib
lrwxrwxrwx 1 root root 8 Jan 12  2021 /sbin -> usr/sbin