81

Two questions, really:

  1. Is there a standard/convention regarding the placement on configuration files?

    For system or quasi-system programs they seem to usually be somewhere in /etc. It seems less clear for plain application programs or programs with insufficient privileges for /etc.

  2. In processing program options is there a standard hierarchy of what takes precedence? E.g. does a command line option override an initialization file and/or an environment variable? Vice versa? Or is this entirely up to the developer?

Michael
  • 8,362
  • 6
  • 61
  • 88
Newton Falls
  • 2,148
  • 3
  • 17
  • 22

7 Answers7

196

You should adhere your application to the XDG Base Directory Specification. Most answers here are either obsolete or wrong.

Your application should store and load data and configuration files to/from the directories pointed by the following environment variables:

  • $XDG_DATA_HOME (default: "$HOME/.local/share"): user-specific data files.
  • $XDG_CONFIG_HOME (default: "$HOME/.config"): user-specific configuration files.
  • $XDG_DATA_DIRS (default: "/usr/local/share/:/usr/share/"): precedence-ordered set of system data directories.
  • $XDG_CONFIG_DIRS (default: "/etc/xdg"): precedence-ordered set of system configuration directories.
  • $XDG_CACHE_HOME (default: "$HOME/.cache"): user-specific non-essential data files.

You should first determine if the file in question is:

  1. A configuration file ($XDG_CONFIG_HOME:$XDG_CONFIG_DIRS);
  2. A data file ($XDG_DATA_HOME:$XDG_DATA_DIRS); or
  3. A non-essential (cache) file ($XDG_CACHE_HOME).

It is recommended that your application put its files in a subdirectory of the above directories. Usually, something like $XDG_DATA_DIRS/<application>/filename or $XDG_DATA_DIRS/<vendor>/<application>/filename.

When loading, you first try to load the file from the user-specific directories ($XDG_*_HOME) and, if failed, from system directories ($XDG_*_DIRS). When saving, save to user-specific directories only (since the user probably won't have write access to system directories).

For other, more user-oriented directories, refer to the XDG User Directories Specification. It defines directories for the Desktop, downloads, documents, videos, etc.

Juliano
  • 39,173
  • 13
  • 67
  • 73
  • This looks really promising. Thanks for mentioning it. If nothing else it eliminated the dot file clutter in the home directory that always irritates me! – Newton Falls Jun 22 '09 at 02:10
  • These environment variables doesn’t work on Mac OS X, even though it is a Unix. In the Terminal, neither `echo $XDG_CONFIG_HOME` nor `env | grep XDG` show anything. Should I hard-code the default values for these variables in my Mac OS X scripts? – Rory O'Kane Jun 22 '12 at 21:46
  • 5
    I see that that specification is by [freedesktop.org](http://www.freedesktop.org/), which works on “interoperability and shared technology for X Window System desktops”. I’m not sure exactly what a “[X Window System](http://en.wikipedia.org/wiki/X_Window_System) desktop” is, but not even xterm within [X11.app](http://en.wikipedia.org/wiki/X11.app) has those environment variables. So this answer doesn’t apply to all Unixes. – Rory O'Kane Jun 22 '12 at 22:29
  • No $XDG_CONFIG_HOME on my system fwiw. I do have $XDG_RUNTIME_DIR, $XDG_SEAT, $XDG_SESSION_ID and $XDG_VTNR. – tobixen Sep 28 '13 at 07:59
  • 10
    As a note to those who mention that these aren't always defined, if those variables don't exist, then you should use the specified default values. For instance, in a shell script you could add to the top of your script `: ${XDG_CONFIG_HOME:=$HOME/.config` and then `$XDG_CONFIG_HOME` would be set to the value in the user's environment or `$HOME/.config` if no value was set. – Brian Campbell May 22 '14 at 20:19
  • This is by far the better answer. Works well in Linux. – JohnMerlino Jun 04 '14 at 14:08
  • 1
    If you're writing cross-platform, for windows, you should fallback `$HOME` to `$USERPROFILE` or `$APPDATA` with `$XDG_DATA_DIRS` pointing to `:$APPDATA:$PROGRAMDATA` . – Tracker1 Jun 26 '15 at 18:35
  • 1
    @RoryO'Kane I believe Brian Campbell answers your question. You should check whether $XDG_CONFIG_HOME, etc., are defined and if so use them, otherwise define them using the default values. – Jorge Bucaran Nov 21 '15 at 07:27
  • 1
    Just as a tip, I'd like to point out that `$XDG_DATA_DIRS` and `$XDG_CONFIG_DIRS` specify **additional** directories to search for files, and `$XDG_DATA_HOME` and `$XDG_CONFIG_HOME` are inherently searched. This point could be a little confusing, I think. – Steve Benner Jan 28 '16 at 01:27
  • And what's the deal here with smth like exo? Is it the same? –  Sep 01 '20 at 18:27
  • I don't really understand why you should use the XDG spec, why not the Linux File Hierarchy Standard FHS? – Didier A. Sep 10 '20 at 01:21
  • As already mentioned by RoryO'Kane, this specification seems to focus on GNU/Linux desktop applications. This specification is not suitable if you're configuring applications on a GNU/Linux server. For that I would consult the Filesystem Hierarchy Standard (see the answer by Fritz G. Mehner). – Serrano Jul 12 '22 at 12:16
73
  1. Generally system/global config is stored somewhere under /etc.
  2. User-specific config is stored in the user's home directory, often as a hidden file, sometimes as a hidden directory containing non-hidden files (and possibly more subdirectories).

Generally speaking, command line options will override environment variables which will override user defaults which will override system defaults.

cletus
  • 616,129
  • 168
  • 910
  • 942
  • 1
    +1 Very simple and precise explanation. Although some setups do not place their config files in /etc but they do so in home directory only. Depends highly on the specific kind of application. – Elitecoder Jun 21 '09 at 16:08
  • 17
    GUI apps seem to be starting to use $HOME/.config as the directory to store per-app, per-user config files. Makes the home directory much tidier and easier to backup your config. – camh Jun 22 '09 at 04:56
40

Newer Applications

Follow XDG Base Directory Specification usually ~/.config/yourapp/* can be INF, JSON, YML or whatever format floats your boat, and whatever files... yourapp should match your executable name, or be namespaced with your organization/company/username/handle to ~/.config/yourorg/yourapp/*

Older Applications

Per-user configuration, usually right in your home directory...

  • ~/.yourapp file for a single file
  • ~/.yourapp/ for multiple files + data usually in ~/.yourapp/config

Global configurations are generally in /etc/appname file or /etc/appname/ directory.

Global App data: /var/lib/yourapp/

Cache data: /var/cache/

Log data: /var/log/yourapp/


Some additional info from tutorialhelpdesk.com

The directory structure of Linux/other Unix-like systems and directory details.

In Windows, almost all programs install their files (all files) in the directory named: 'Program Files' Such is not the case in Linux. The directory system categorizes all installed files. All configuration files are in /etc, all binary files are in /bin or /usr/bin or /usr/local/bin. Here is the entire directory structure along with what they contain:

/ - Root directory that forms the base of the file system. All files and directories are logically contained inside the root directory regardless of their physical locations.

/bin - Contains the executable programs that are part of the Linux operating system. Many Linux commands, such as cat, cp, ls, more, and tar, are locate in /bin

/boot - Contains the Linux kernel and other files needed by LILO and GRUB boot managers.

/dev - Contains all device files. Linux treats each device as a special file. All such files are located in /dev.

/etc - Contains most system configuration files and the initialisation scripts in /etc/rc.d subdirectory.

/home - Home directory is the parent to the home directories of users.

/lib - Contains library files, including loadable driver modules needed to boot the system.

/lost+found - Directory for lost files. Every disk partition has a lost+found directory.

/media - Directory for mounting files systems on removable media like CD-ROM drives, floppy disks, and Zip drives.

/mnt - A directory for temporarily mounted filesystems.

/opt - Optional software packages copy/install files here.

/proc - A special directory in a virtual filesystem. It contains the information about various aspects of a Linux system.

/root - Home directory of the root user.

/sbin - Contains administrative binary files. Commands such as mount, shutdown, umount, reside here.

/srv - Contains data for services (HTTP, FTP, etc.) offered by the system.

/sys - A special directory that contains information about the devices, as seen by the Linux kernel.

/tmp - Temporary directory which can be used as a scratch directory (storage for temporary files). The contents of this directory are cleared each time the system boots.

/usr - Contains subdirectories for many programs such as the X Window System.

/usr/bin - Contains executable files for many Linux commands. It is not part of the core Linux operating system.

/usr/include - Contains header files for C and C++ programming languages

/usr/lib - Contains libraries for C and C++ programming languages.

/usr/local - Contains local files. It has a similar directories as /usr contains.

/usr/sbin - Contains administrative commands.

/usr/share - Contains files that are shared, like, default configuration files, images, documentation, etc.

/usr/src - Contains the source code for the Linux kernel.

/var - Contains various system files such as log, mail directories, print spool, etc. which tend to change in numbers and size over time.

/var/cache - Storage area for cached data for applications.

/var/lib - Contains information relating to the current state of applications. Programs modify this when they run.

/var/lock - Contains lock files which are checked by applications so that a resource can be used by one application only.

/var/log - Contains log files for different applications.

/var/mail - Contains users' emails.

/var/opt - Contains variable data for packages stored in /opt directory.

/var/run - Contains data describing the system since it was booted.

/var/spool - Contains data that is waiting for some kind of processing.

/var/tmp - Contains temporary files preserved between system reboots.

Tracker1
  • 19,103
  • 12
  • 80
  • 106
10

Please do also consult the Filesystem Hierarchy Standard.

Fritz G. Mehner
  • 16,550
  • 2
  • 34
  • 41
3
  1. Typically in a dotfile (like .myprogramrc) in the user's home directory.
  2. It is of course up to the programmer but normally command line arguments override everything else. If environment variables are used it is usually as an alternative to the command line arguments or to specify where the configuration is located.
Fredrik
  • 5,759
  • 2
  • 26
  • 32
2

For user configuration I've noticed a tendency towards moving away from individual ~/.myprogramrc to a structure below ~/.config. For example, Qt 4 uses ~/.config/<vendor>/<programname> with the default settings of QSettings. The major desktop environments KDE and Gnome use a file structure below a specific folder too (not sure if KDE 4 uses ~/.config, XFCE does use ~/.config).

bluebrother
  • 8,636
  • 1
  • 20
  • 21
  • 4
    What you are seeing is the XDG Base Directory Specification, http://standards.freedesktop.org/basedir-spec/latest/ – CesarB Jun 21 '09 at 16:59
1

(1) No (unfortunately). Edit: The other answers are right, per-user configuration is usually stored in dot-files or dot-directories in the users home directory. Anything above user level often is a lot of guesswork.

(2) System-wide ini file -> user ini file -> environment -> command line options (going from lowest to highest precedence)

balpha
  • 50,022
  • 18
  • 110
  • 131