4

I have noticed that essentially all the files in /usr/bin are stand-alone executables, rather than a directory containing the executable plus other files that the executable might need (such as configuration files, data files, etc.)

If I develop an application that consists of multiple files, where should it be saved? My first instinct was to save the application's directory in /opt and make a soft link to the executable in /usr/bin. However, Google Chrome is the only application on my computer that does this, making me think that there's a more standard approach.

  • 1
    In a docker container! But it depends a bit - what sort of app and what sort of files. It's not too uncommon to split files between the "key" directories (/var, /etc, /usr etc.). Don't necessarily assume you have to softlink into /usr/bin either. Let users sort out their own path. – Sobrique Dec 31 '15 at 21:25

2 Answers2

3

There are two main ways to organize files from installed software: by package, or by type.

Unix systems tend to organize program files by type: executables in /usr/bin, executables that are only useful to the system administrator in /usr/sbin, code libraries and other processor-architecture-dependent files in /usr/lib, data files that don't depend on the processor type in /usr/share, manual pages in /usr/man, miscellaneous documentation /usr/doc, etc. (This is not an exhaustive list and many variations exist.) I used the prefix /usr, but there are in fact typically three such fanouts: at / for programs that are needed at boot time (this is sometimes merged with /usr as the distinction is not always relevant), at /usr for programs that come with the operating system, and at /usr/local for programs installed manually by the system administrator.

On most Linux systems, the distinction between /usr and /usr/local is that /usr (and /) is managed by the package manager, and /usr/local isn't. So if your application is installed using the by-type structure, it should go under /usr when distributed as a package (rpm, deb, …) and under /usr/local when not distributed as a package (e.g. if it's distributed as an archive to be unpacked manually).

Configuration files typically all go in /etc because they're meant to be modified by the system administrator. If possible, have your application read configuration data from /etc and either /usr/etc or /usr/local/etc as appropriate, with settings in /etc/ overriding the ones in /usr/etc or /usr/local/etc. It's common to lump configuration data with other data under /usr/share or /usr/local/share, so you'll find that many systems don't have /usr/etc or /usr/local/etc.

The upside of the by-type organization is that files are placed where they'll be used. All executables are in the directories in the executable search path ($PATH), all libraries are in the library search path, all manual pages are in the man page search path, etc. The one limitation of this organization is that it requires a package manager to keep track of which files are installed by each package. Since most software on Linux is distributed via a package manager, most software ends up under /usr.

Another way to organize files is by package, and the standard place for that is /opt. It's typically organized as /opt/APPLICATION/bin, /opt/APPLICATION/lib, etc., sometimes with an additional level /opt/AUTHOR/APPLICATION/bin etc. Applications are free to manage their directory however they want, though; some put miscellaneous files directly in /opt/APPLICATION. This makes package management trivial (just unpack in the right place, use ls to list installed software, use rm -r to uninstall) but makes it harder to use the software: the administrator or the user need to add the appropriate locations to search paths, or to use full paths, or to create symbolic links.

Files under /opt are usually managed manually (that's the main point of this organization), but it's possible to have packages there that are managed by a package manager. For example Chrome's deb packages put it under /opt. An advantage of doing that is that Chrome is always in /opt/google/chrome regardless of how it was installed; possibly this makes cross-distribution support a little easier.

If you want the details of how applications and distributions should organize files on Linux, read the FHS.

In a nutshell:

  • When building a package (deb, rpm, …), install under /usr, with the distribution's choice of directories (e.g. for /usr/man vs /usr/share/man, /usr/lib vs /usr/libexec, /usr/lib vs /usr/lib64, etc.).
  • When installing directly (e.g. make install), default to installing under /usr/local (with the default subdirectories: executables in /usr/local/bin, data files in /usr/local/share/APPLICATION, etc.), and do support other choices that the system administrator might make. Note that the directory where the files will be copied during installation might not be the same as the directory where the files will be used, for example due to the use of stow (see Keeping track of programs).

/opt is also a possibility in either case, but you're putting more burden on the system administrator.

  • But the question remains: if selecting /usr/local/, and the application consist of e.g. five Python files (not runnable as separate applications), do you put them in a subdirectory /usr/local/bin/myapp? Then it won't be found by searching PATH – Gauthier Oct 12 '23 at 12:50
  • @Gauthier If the files are not runnable as separate applications, then they should not be on $PATH. – Gilles 'SO- stop being evil' Oct 12 '23 at 14:09
  • Right, so if I want an application to be runnable, in PATH, but it consist of multiple files, say Python. What would best practices dictate? – Gauthier Oct 13 '23 at 11:13
  • @Gauthier Things that the user can execute directly go into /usr/local/bin. Auxiliary files that the user doesn't access go under /usr/local/lib or /usr/local/share. Python modules that can be used by other applications go under /usr/local/lib/pythonN.N where N.N is the python version. – Gilles 'SO- stop being evil' Oct 13 '23 at 13:11
1

If you're making a package, it does depend somewhat on the distro you're targeting. You can follow the Filesystem Hierarchy Standard. Debian follows FHS, with some exceptions. Essentially:

  • /etc: Host-specific system configuration
  • /usr/bin: Most user commands
  • /usr/lib: Libraries for programming and packages
  • /usr/share: Architecture-independent data

On Debian-based systems for packages that support multiple architectures, the architecture-independent data is often split off into a separate package.

See, for example, how apache2, apache2-bin, apache2-data and apache2-doc packages on Ubuntu are organised.

muru
  • 72,889
  • Not mentioning that /usr is only for files managed by the package manager and /usr/local should be used instead makes this answer bad advice. – Gilles 'SO- stop being evil' Dec 31 '15 at 21:41
  • @Gilles I assumed that we were talking of packages ... and now I have edited the answer to state that assumption explicitly. – muru Dec 31 '15 at 21:42