75

In my OSGi-based Java application I am developing a bundle to provide the rest of the system with access to the file system. In addition to providing access to the user home directory, I also wish to provide access to a non-user specific area. Exactly what this area will be used for is as yet undetermined, but it will not be for preferences (handled by a different bundle), however it may be used to store data that could change at runtime.

I intend on using the following directories for this purpose:

Where is a sensible equivalent in Linux and how do I get a handle on it from my Java code?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
William
  • 13,332
  • 13
  • 60
  • 73
  • Can you be more specific about what type of data you're storing? Is it data that's static (config files, static information, etc.) or is it data that's changed at runtime? I've answered below under the assumption of the latter, but after re-reading your question I'm not entirely sure what you're after. – Rob Hruska Oct 02 '09 at 15:47
  • I have reworded the question to (hopefully) clarify the situation somewhat. – William Oct 02 '09 at 16:55
  • Similar question - https://unix.stackexchange.com/questions/70700/whats-the-most-appropriate-directory-where-to-place-files-shared-between-users . – Victor Yarema Nov 01 '17 at 14:47
  • Similar question - https://superuser.com/questions/635289/what-is-the-recommended-directory-to-store-website-content . – Victor Yarema Nov 01 '17 at 14:47

8 Answers8

114

It depends on what kind of data you're planning on storing. This answer is under the premise that you're storing and modifying data at run time.

Contrary to what others have suggested, I would recommend against using /usr/share for storage. From the Filesystem Hierarchy Standard:

The /usr/share hierarchy is for all read-only architecture independent data files.

As you're modifying data, this goes against the read-only nature of the /usr subsystem.

A seemingly better place to store your application state data would be /var, or more specifically, /var/lib. This also comes from the Hierarchy Standard. You could create a /var/lib/myapp, or if you're also using things like lock files or logs, you could leverage /var/lock or /var/log.

Have a deeper look at the standard as a whole (linked to above)—you might find a place that fits what you want to do even better.

Like Steve K, I would also recommend using the Preferences API for application preference data.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
  • 13
    Writing program data to `/var` usually requires superuser privileges. What to do if the app is running as user? – emkey08 Mar 06 '15 at 07:46
  • 8
    @MathiasKunter - If the app is running as a specific user, you should set up the appropriate `/var/...` directories (e.g. `/var/log/my-app/`, `/var/lib/my-app/`, etc.) to give read/write access to that user or its group. Alternatively, if it's an actual human user you're talking about, you could consider using their home directory (e.g. `~/.my-app/...`). – Rob Hruska Mar 09 '15 at 03:40
  • 3
    If an app is running as an ACTUAL user, the data should be stored under that users $HOME. If it is a system user, the install (as root or similar) should give that user ownership of its files and directories under /var, and add the user to any groups needed for access to additional devices/directories/files. – Joshua Clayton Oct 12 '17 at 15:37
  • 1
    I guess the official FHS is now found [here](https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html)? – djvg Oct 01 '19 at 08:37
  • Storing in home programatically can be nightmarish as it is not an absolute path – Eric Burel Jul 24 '20 at 08:14
  • What if I want store a database file (sqlite) - it hardly fits lib.. Is it? – Boppity Bop Dec 03 '20 at 17:26
  • @BoppityBop, looking through my /var/lib I find several (pretty known) tools that place their database files there. For example fail2ban – trallnag Jun 26 '21 at 16:45
  • If there are unscrupulous developers who put their dbs in a lib (which is library - static file eg dlls) it's their problem. I would not do it – Boppity Bop Jun 27 '21 at 17:04
  • 3
    @BoppityBop `/var/lib` is for "variable state information", not static library files. – Joe Coder Jan 17 '22 at 19:44
62

It depends.

  • Global configuration → /etc/appname

  • Read-only, independent of machine architecture → /usr/share/appname

  • Read-only, machine specific → /usr/lib/appname

  • Read-write → /var/lib/appname

There isn't any guarantee for completeness. Please check the Filesystem Hierarchy Standard.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
starblue
  • 55,348
  • 14
  • 97
  • 151
7

Since you are using Java, look at the Preferences API.

From the introduction:

Applications require preference and configuration data to adapt to the needs of different users and environments. The java.util.prefs package provides a way for applications to store and retrieve user and system preference and configuration data. The data is stored persistently in an implementation-dependent backing store. There are two separate trees of preference nodes, one for user preferences and one for system preferences

I'd let the built-in API do the work.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Steve K
  • 19,408
  • 6
  • 52
  • 50
  • Thanks. We will be implementing a preferences service also (OSGi based), however also need access to the file system for other purposes. – William Oct 02 '09 at 15:19
  • The Linux implementation of the Preferences API does use the file system. Not sure why it wouldn't suite your needs - can you expand on it more? You can also create your own backing store for the preferences - if you want to take things that far. – Steve K Oct 02 '09 at 15:34
6

The freedesktop.org (previously known as the X Desktop Group) project has defined some standards for this in the XDG Base Directory Specification.

In your case, I'd have a look at $XDG_DATA_DIRS:

$XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS should be seperated with a colon ':'.

If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.

I warmly suggest to read the XDG Base Directory Specification.

Community
  • 1
  • 1
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • On GNU Linux, [GNU Coding Standards](https://www.gnu.org/prep/standards/) are usually followed. There is probably a lot of overlap between GNU and XDG. Regarding the XDG directories, they don't seem to make accommodations for non-user-specific runtime data that is often stored somewhere in `/var`. – jww Dec 05 '19 at 12:56
2

In the /usr/share or /usr/local/share folders.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
catwalk
  • 6,340
  • 25
  • 16
2

According to Filesystem Hierarchy Standard (which seems to be updated and correct as of July 2015)...

Assuming that the datafiles are understood to not meet the requirements of /tmp or /var/tmp then /usr/local/share/theApp or /usr/local/theApp.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
david1024
  • 121
  • 2
0

If it is non-user-specific, you can probably store it under /usr/share/appname

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Locksfree
  • 2,682
  • 23
  • 19
0

You could use the System.getProperty("user.home") to get the users home, so it's more platform independent.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
James R. Perkins
  • 16,800
  • 44
  • 60
  • I will be using that when I need access to the user's home, however my question is related to the non-user specific area (which can be obtained using System.getenv("ALLUSERSPROFILE") on Windows, but this does not work on Linux). – William Oct 02 '09 at 15:14
  • Ah, sorry about that. I misunderstood what you were after. The Properties as suggested earlier has support for all users. I know in Windows it stores it in the registry, not sure where it stores the info on Linux. – James R. Perkins Oct 02 '09 at 16:08