629

According to the Filesystem Hierarchy Standard, /opt is for "the installation of add-on application software packages". /usr/local is "for use by the system administrator when installing software locally". These use cases seem pretty similar. Software not included with distributions usually is configured by default to install in either /usr/local or /opt with no particular rhyme or reason as to which they chose.

Is there some difference I'm missing, or do both do the same thing, but exist for historical reasons?

Patches
  • 6,632

8 Answers8

570

While both are designed to contain files not belonging to the operating system, /opt and /usr/local are not intended to contain the same set of files.

/usr/local is a place to install files built by the administrator, typically by using the make command (e.g., ./configure; make; make install). The idea is to avoid clashes with files that are part of the operating system, which would either be overwritten or overwrite the local ones otherwise (e.g., /usr/bin/foo is part of the OS while /usr/local/bin/foo is a local alternative).

All files under /usr are shareable between OS instances, although this is rarely done with Linux. This is a part where the FHS is slightly self-contradictory, as /usr is defined to be read-only, but /usr/local/bin needs to be read-write for local installation of software to succeed. The SVR4 file system standard, which was the FHS' main source of inspiration, is recommending to avoid /usr/local and use /opt/local instead to overcome this issue.

/usr/local is a legacy from the original BSD. At that time, the source code of /usr/bin OS commands were in /usr/src/bin and /usr/src/usr.bin, while the source of locally developed commands was in /usr/local/src, and their binaries in /usr/local/bin. There was no notion of packaging (outside tarballs).

On the other hand, /opt is a directory for installing unbundled packages (i.e. packages not part of the Operating System distribution, but provided by an independent source), each one in its own subdirectory. They are already built whole packages provided by an independent third party software distributor. Unlike /usr/local stuff, these packages follow the directory conventions (or at least they should). For example, someapp would be installed in /opt/someapp, with one of its command being /opt/someapp/bin/foo, its configuration file would be in /etc/opt/someapp/foo.conf, and its log files in /var/opt/someapp/logs/foo.access.

Elliptical view
  • 3,921
  • 4
  • 27
  • 46
jlliagre
  • 61,204
  • 114
    /usr/local, for self, inhouse, compiled and maintained software. /opt is for non-self, external, prepackaged binary/application bundle installation area. Hmmm...we do not have C:\program files for everything ;-) – Nikhil Mulley Feb 02 '12 at 12:49
  • 6
    "On the other hand, /opt is a directory where to install unbundled packages" What does 'unbundled' packages mean here? – Kevin Wheeler Aug 16 '15 at 01:54
  • 6
    @KevinWheeler That is explained in the next sentence. Unbundled means packages not part of the Operating System distribution but provided by an independent source. – jlliagre Aug 16 '15 at 01:59
  • I know that this question asked about the FHS, but I want to throw it out there that Unix flavors will sometimes deviate from the FHS. For example, this answer is not applicable to Ubuntu. – Kevin Wheeler Dec 06 '15 at 10:53
  • 2
    @jlliagre the centos docs* state "For instance, if the /usr/ directory is mounted as a read-only NFS share from a remote host, it is still possible to install a package or program under the /usr/local/ directory" I don't know who is right, but this seems to be in contradiction to your claim about an area where FHS is weak. (*source https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s3-filesystem-usr-local.html) – Kevin Wheeler Dec 06 '15 at 11:44
  • 1
    @KevinWheeler That's precisely the weakness I'm referring to. Installing a package or a program in a remote, read-only directory is just impossible. The workaround would be to mount a local file system on /usr/local but this looks more like a makeshift job than a something properly designed. – jlliagre Dec 06 '15 at 13:05
  • 2
    “I'm still waiting for /opt/local to show up...” — Rob Landley – vhs Feb 09 '19 at 20:20
  • 2
    @JoshHabdas I did create a /opt/local directory on some of my machines (violating the standard). I'm skeptical about Rob Landley's statements regarding the /home directory creation. AFAIK, it showed up at least 15 years after what he states. There is no evidence of its usage in early Unix. Version 7 (1977) wasn't documenting or using it. It first officially appeared between 1985 and 1988. – jlliagre Feb 09 '19 at 20:58
  • 1
    From what I understood by reading the specifications of FHS, /usr is read-only for other hosts, but still read & write within the host, hence there is no reason to think that you cannot do installation of software in /usr. – mikl Feb 19 '19 at 21:17
  • @mikl Well, /usr is indeed writeable but only on one host. Obviously, there are workarounds should there is a need to create local files on a client. The simplest is to mount a read-write file system (or better bind mount another directory) on top of /usr/bin but then the ability to share software from the server is lost. – jlliagre Feb 19 '19 at 23:15
  • @jlliagre I think /usr/local is supposed to be on a different partition than /usr to have /usr be mounted as read-only by other hosts. – mikl Feb 24 '19 at 08:45
  • Yes, that's one of the workarounds I intended to state in my previous comment but I unfortunately miswrote /usr/bin while I meant /usr/local. – jlliagre Feb 24 '19 at 09:12
  • 1
    As I recall, back in the 60s/70s, there was only one host that could access each hard drive. It wasn't until network drives became standard (in the 80s) that you had drives that could be mounted into multiple hosts. So the question of who mounted /usr as ro or rw wasn't being asked when the questions of what got installed where were being standardized. – Jesse Chisholm May 12 '20 at 21:17
  • 11
    I'll add that by default /usr/local/bin is on the PATH while the /opt/<package>/bin folders will not automatically be added to the PATH. So when I install a pre-built software, I put it in /opt but I will add a symlink for it in /usr/local/bin if I need to start it from the command line. – Didier A. Nov 01 '20 at 08:21
  • @KevinWheeler Bundled packages are the ones selected by a distribution builder to be part of it, unlike unbundled packages that are provided by third-parties. – jlliagre Jul 25 '22 at 16:47
  • @jlliagre So in Ubuntu, would packages in the Universe and Multiverse (and PPAs and other repositories) be considered unbundled? While packages in main and restricted are bundled? I guess not, since /usr/local is for packages built by the admin typically with the make command, not for packages installed using a package manager (ie things in universe and multiverse)... So is it just packages that installed by default on a fresh OS install that are considered to be bundled? – Kevin Wheeler Aug 23 '22 at 01:13
  • self-contradictory

    no you can bind mount /usr/local as read write and keeping /usr as ro

    – Et7f3XIV Apr 28 '23 at 15:20
  • @Et7f3XIV Yes, of course you can do it but that's kind of a kludge. – jlliagre Apr 28 '23 at 19:26
124

The basic difference is that /usr/local is for software not managed by the system packager, but still following the standard unix deployment rules.

That's why you have /usr/local/bin, /usr/local/sbin /usr/local/include etc...

/opt on the other hand is for software that doesn't follow this and is deployed in a monolithic fashion. This usually includes commercial and/or cross-platform software that is packaged in the "Windows" style.

Šimon Tóth
  • 8,238
  • 17
    I disagree about your monolithic point. The FHS standard says packages installed in /opt subdirectories must have their host specific files be installed outside /opt, respectively under /etc/opt/package for configuration files and /var/opt/package for logs, spool and similar. /opt is actually closer to the unix deployment rules than /usr/local, which put everything under a directory that should be read-only but can't be for obvious reasons. – jlliagre Apr 04 '13 at 09:03
  • 10
    Sure, if I were making an opt package and wanted to claim FHS compliance. Otherwise the standard is more what you'd call "guidelines". Just because NetBeans doesn't use /etc/opt/netbeans isn't going to keep me from putting it in /opt for system-wide or $HOME/.local/opt for a single-user. – jla May 14 '15 at 18:59
  • 3
    @jla I assume your last comment was directed to me so please use @ xxx when replying to someone else that the OP or the reply author. About /etc/opt, the FHS doesn't say it is a recommended location (as a guideline) but a mandatory location. You or Netbeans developer are free to violate that standard as there is no authority to enforce it, but don't tell doing it wrong is the way to go. It is just an unfortunate misunderstanding or deliberate violation. – jlliagre May 22 '15 at 11:15
  • 16
    @jlliagre As an administrator of my system, the FHS is a set of guidelines. The /opt directory is the common sense well-established place to put monolithic /opt/ or /opt/ software. When I install a package that wants to use <package|provider>/all/data/required/to/support, it's going into opt/ even if provider fails to follow every detail of the latest FHS. I might send an email or report a bug, but I'm not going to put that monolithic package somewhere else to feel better about FHS on my system. – jla May 27 '15 at 18:04
  • 2
    @jlliagre I've installed lot of stuff in /opt and no file is created in /etc/opt. Should? – m3nda Jan 26 '16 at 00:38
  • 3
    @erm3nda That means the packages you installed do violate the FHS. Not sure to get what you mean with "Should?" – jlliagre Jan 26 '16 at 00:46
  • 3
    @jlliagre. Meaning: should the software installed in /opt create regular .conf files inside the /etc/opt folder? I have as example Firefox, Hashcat and others that were not available on the repos. /etc/opt is totally empty. – m3nda Jan 26 '16 at 01:11
  • 1
    @erm3nda Yes they should, assuming they they want to follow the FHS, but they don't. (sorry for the one year delay answering, I missed your comment...) – jlliagre Jan 28 '17 at 20:42
  • 1
    @jlliagre Well, lets explain it. Case of software seriously developed/deployed ... yes, it follows FHS even if was installed into /opt. Now, case of shit app that is just a bunch of files self contained and using relative paths on its own rules (or a portable at all) ... well, that will not follow it. So finally depends on how the package was designed (thus installed). Usually, software well packaged as .deb will follow FHS ever, and an untar'ed package will not do so often. – m3nda Jan 30 '17 at 18:33
  • 2
    @jlliagre Are you implying that there is some software which is simply not possible to install in a FHS compliant way (without modifying said software)? Where should a user install a monolithic program which defies the usual conventions, according to you? – JBentley Feb 15 '19 at 17:49
  • 1
    @JBentley FHS says: "No other directories, except those listed below, may be in /usr/local after first installing a FHS-compliant system." So I get from that you should only install things in /usr/local if it respects the usr/local strucure, so files go in /bin, /lib, /man, /etc, and so on. It also says "If a configuration file must reside in a different location in order for the package or system to function properly, it may be placed in a location other than /etc/opt/." Thus, in my opinion, 3rd party packages which just store all their data in a monolithic style should go in /opt – Didier A. Oct 17 '19 at 05:18
  • 2
    Oh for Christ's sake. I'm now more convinced than ever before that none of these directories mean anything. Things were calm in the early 80's, but by the late 80's, with the rush to mimic the Apollo and Sun workstations, all kinds of oddities started showing up. I always figured a lot of it had to do with the increased popularity of BSD over SystemV (until System V r4) but at this point, who knows.... – tgm1024--Monica was mistreated Jan 19 '20 at 06:54
20

They are very similar indeed, and the use of one or the other is more a matter of opinion. Linux journal had this point/counterpoint discussion about this exact topic here.

philfr
  • 1,088
17

For me, personally, it's what Bill said in @philfr's link:

On a development system, or a sandbox, having an /opt directory where you can just toss things and see if they work makes a whole lot of sense. I know I'm not going to go through the effort of packaging things myself to try them out. If the app doesn't work out, you can simply rm the /opt/mytestapp directory and that application is history. Packaging may make sense when you're running a large deployment (there are times when I do package apps), but lots of times, it's nice to toss stuff in /opt.

Unfortunately, most make install scripts pushes files into /usr/local instead of just making a symlink there :-/

pepoluan
  • 1,323
  • 2
    What would be the point? If you are going to make the symlink anyway, why not just put the original file there in the first place? – Šimon Tóth Apr 18 '11 at 09:54
  • 12
    Just to comment on the make install target pushing files into /usr/local; this functionality is easily changeable by passing a --prefix= command line parameter to the ./configure script, or if there is no ./configure script, you can pass a parameter to the make target like so: make --prefix=/usr install. – Sean C. Apr 18 '11 at 11:45
  • 4
    Is /opt a standard directory included in $PATH? I know /usr/local is. – LawrenceC Apr 18 '11 at 14:13
  • 9
    @Let_Me_Be the benefit would be that it's very easy to keep older versions. Let's say I have 2 versions of 'foo', located in /opt/foo-1.1 and /opt/foo-1.2. When I upgrade, foo symlink in /usr/local/bin points to foo-1.2. If for some reason I need to rollback, I just replace the symlink with one that points to foo-1.1 instead. If 1.2 is okay after several weeks, a quick rm -rf /opt/foo-1.1 removes the older version quickly and cleanly. – pepoluan Apr 18 '11 at 14:41
  • 1
    @Sean indeed. but sometimes lots of crud gets sent there, too. I'd rather have the cruds not littering my /usr/local – pepoluan Apr 18 '11 at 14:42
  • 8
    @ultrasawblade no, it is not. and never should be. after all, according to FHS, /opt must be subdivided into subdirs bearing the name of the package. cramming everything into PATH is a surefire way to disaster. rather, apps should install themselves under /opt, and symlinks their user-invoked programs into /usr/local/bin (or sbin). – pepoluan Apr 18 '11 at 14:45
  • @LawrenceC, Why would it be? Doesn't that sort of defeat the purpose of opt? – Pacerier Nov 01 '17 at 22:23
  • 1
    Years later, I now understand why it is not. – LawrenceC Nov 02 '17 at 04:02
  • 2
    FHS 3 says: "The directories /opt/bin, /opt/doc, /opt/include, /opt/info, /opt/lib, and /opt/man are reserved for local system administrator use. Packages may provide "front-end" files intended to be placed in (by linking or copying) these reserved directories by the local system administrator, but must function normally in the absence of these reserved directories." So while I agree, /opt should not be on the path, and symlinks should be made in /usr/local/, it now seems that /opt/bin, /opt/man et al. are also meant to serve that purpose. So adding /opt/bin to the PATH would make sense. – Didier A. Oct 17 '19 at 05:22
15

I have a slightly different take on this issue.
While everything in jlliagre's answer is correct, the practical application for me, when deploying software in a cluster, comes down to default environment variables and default reuse of libs.

Simply put - /usr/local and all its child dirs are in the appropriate env vars such as PATH and MANPATH, and /usr/local/lib{,64} are in ldconfig's (/etc/ld.so.conf.d/).

/opt/ OTOH is not — which is both advantageous when requiring multiple versions or conflicting packages to co-exist in the system, but requires some sort of environment management (e.g., environment-modules or software collections), and disadvantageous in that it would potentially "waste" storage space by duplicating shared libraries, as each installation in /opt can be completely self contained.

For the shared nature of /usr/local to work, it is assumed that e.g. binaries are installed directly to /usr/local/bin (and man pages to appropriate /usr/local/share/man/...) rather than /usr/local/app/{bin,share/man,...} etc.

Dani_l
  • 4,943
14

First, I don't think there is a strict answer; different adminstrators will have different opinions, according to their background. Historically, /usr/local came first; it was the convention in Berkley, IIRC. At one point during the development of System V, if I'm not mistaken (this is all a long time ago, and I didn't take notes), there was a decision or a desire to be able to mount /usr read-only, which meant you couldn't add new software to it; that may have been why /opt was invented. As it happens, there was just so much existing software that did write to /usr that that idea never really got off the ground.

My personal preference is /opt, with a separate subdirectory for each product; this makes removing a product a simple case of rm -fr. But if all of your software is installed via a good package manager, it doesn't matter, and if the software you install doesn't strictly obey these conventions, and writes configurations and such somewhere under /usr, it doesn't matter either, although for the opposite reasons.

  • 1
    """all of your software is installed via a good package manager""" that's impossible unless you use only oft-used software. – Pacerier Nov 01 '17 at 22:21
  • 2
    @Pacerier it's possible, it depends what distro you're using. Whatever the software is, it's probably in the Arch User Repository, and if it isn't, a PKGBUILD is relatively easy to write. – StarlitGhost Nov 02 '18 at 10:17
5

I have a slightly different take on this old topic.

  • If I am working on a new tool that I intend to be a standard part of the OS.
    • I install it to /usr/local and ask my local users to alpha test it.
  • When I want to beta test it with people outside my company ...
    • I put it in /opt because to them it is a 3rd party product.
    • I may still have my cutting edge version in my own /usr/local
    • They probably get a tarball, unless I've set up my own package server.
    • but maybe I do publish it with a 0.X.Y SemVer number.
  • When the larger community has finally accepted my tool as the OS component it is meant to be
    • The official package gets re-bundled as part of the OS
    • no longer in /usr/local
    • no longer in /opt
    • no longer a mere tarball

If I want it to be a smooth acceptance, then I follow the FHS and I package it properly from the very beginning.

If I was a cowboy to start with, and didn't follow FHS, or just made tarballs and never packaged it, then there is re-factoring work required before it can be accepted.

Some packages/tarballs never get out of /opt, some never get out of /usr/local

But in my opinion, this flow is likely what was intended back then when it was chosen.

Jesse Chisholm
  • 200
  • 2
  • 5
4

In summary, my gut answer ...

Having used my fair share of FreeBSD since 2.2.6 and Red Hat Linux since version 9 ...

/usr/local == Old School Conventions
/opt       == New School Conventions

The arrangement of things on UNIX/Linux file systems has more to do with conventions and tradition, than absolute logic.

Otherwise, I mostly agree with everyone else. :-)

There is always some exception to the rule. At the end of the day, you decide what is best for your set up (when you can).