Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
How to manage user-specific application data on Linux?
I am developing an application that targets Linux-based OS, and I need to store the user's configuration, metadata and other things in a persistent way (i.e. on the file system).
I know that one common approach is to store user-specific application data in a "dotfile" in the user's $HOME
directory (e.g. a file called $HOME/.my-application-name
). However, I would like to be able to store and manage several different files in the same way without polluting the user's $HOME
directory.
What is the idiomatic way of doing this?
3 answers
The traditional approach is to create either a single dotfile, or a single dot-directory, directly under the user's home directory, named for your application. Thus ~/.thromblemeisteradmin
(which could be a plain file or a directory containing any number of files). Sometimes a directory has a name suffix of .d
, but that is redundant if there's only a directory. Similarly, for historical reasons files have often had a rc
suffix; thus ~/.procmailrc
for procmail
. If it's a directory and appropriately named, it's generally assumed to be "owned" by the respective application, but entirely possibly under the control of the user.
However, while many applications still do this, this practice is discouraged on Linux since quite some time ago.
These days, the recommended location for such data, per the Linux Filesystem Hierarchy Standard version 3.0 (authoritative standard document) and the XDG Base Directories specification version 0.8 is to, among others (the XDG base dirs specification has a more complete list and is the authoritative reference for the usage of each):
- store user-specific configuration data in an appropriately-named subdirectory of
$XDG_CONFIG_HOME
- store relatively important user-specific data in an appropriately-named subdirectory of
$XDG_DATA_HOME
- store relatively unimportant user-specific data, such as current application state or recovery files, in an appropriately-named subdirectory of
$XDG_STATE_HOME
- store readily recreatable user-specific data, such as cache data, in an appropriately-named subdirectory of
$XDG_CACHE_HOME
Each of these will very likely appear somewhere within a subdirectory of /home
, but you can't necessarily count on that; consider ~root
which is often /root
or on some systems /var/root
. Do keep in mind that the $XDG_*
environment variables might not be set; modern systems probably set them in their default configuration, but there's still the possibility that they are unset, in which case the specification provides fallback values for each.
If you really only need a single file for any of these, then substituting a file for the directory is generally acceptable; however, many applications still create a directory, if for no other reason then for future-proofing purposes. So it's not at all uncommon to see something like $XDG_CONFIG_HOME/<someapplication>/config.ini
, with nothing else under that directory. The specification also calls out things like filesystem permissions and provides examples of how to handle failures. It's not that long; if you are considering doing this, taking the few minutes to read through the actual XDG base directories specification is probably time well spent.
As an example, something like a hypothetical SSH client adhering to the XDG base dirs spec might store its configuration somewhere under $XDG_CONFIG_HOME
, host and user keys somewhere under $XDG_DATA_HOME
, and optimization data (I'm not sure exactly what that might be, but with the advent of post-quantum cryptography, who knows what might be useful?) somewhere under $XDG_CACHE_HOME
.
1 comment thread
Indeed, the $HOME/.application-name
is the old way. Doing that nowadays is frowned upon (this is an example of what happens if you try), mostly because, as you said, it clutters the home directory.
Instead, stick to the XDG Base Directory Specification. The most important points are:
There is a single base directory relative to which user-specific data files should be written. This directory is defined by the environment variable
$XDG_DATA_HOME
.There is a single base directory relative to which user-specific configuration files should be written. This directory is defined by the environment variable
$XDG_CONFIG_HOME
.
They usually boil down to $HOME/.local/share
and $HOME/.config
, and, as the document says, those paths should be assumed if the corresponding environment variables are unset or empty.
0 comment threads