DAEMON(1)
โจ daemon(1) โจ โ User Commands
๐ NAME ๐
daemon โ turns other processes into daemons. ๐
๐ธ SYNOPSIS ๐ธ
usage: daemon [options] [--] [cmd arg...]
options:
-h,--helpโ Print a help message then exit. โจ-V,--versionโ Print a version message then exit. ๐-v,--verbose[=level]โ Set the verbosity level. ๐-d,--debug[=level]โ Set the debugging level. ๐ฆ-C,--config=pathโ Specify the system configuration file. ๐ธ-N,--noconfigโ Bypass the system configuration file. ๐-n,--name=nameโ Guarantee a single named instance. ๐-X,--command="cmd"โ Specify the client command as an option. ๐ซถ-P,--pidfiles=/dirโ Override standard pidfile location. ๐ญ-F,--pidfile=/pathโ Override standard pidfile name and location. ๐ฅ-u,--user=user[:[group]]โ Run the client asuser[:group]. ๐-R,--chroot=pathโ Run the client withpathas root. ๐-D,--chdir=pathโ Run the client in directorypath. โญ-m,--umask=umaskโ Run the client with the given umask. ๐-e,--env="var=val"โ Set a client environment variable. ๐-i,--inheritโ Inherit environment variables. ๐-U,--unsafeโ Allow execution of unsafe executable. ๐ง-S,--safeโ Disallow execution of unsafe executable. ๐-c,--coreโ Allow core file generation. ๐--nocoreโ Disallow core file generation (default). โจ-r,--respawnโ Respawn the client when it terminates. ๐-a,--acceptable=#โ Minimum acceptable client duration (seconds). โณ-A,--attempts=#โ Respawn#times on error before delay. ๐-L,--delay=#โ Delay between respawn attempt bursts (seconds). ๐ฆ-M,--limit=#โ Maximum number of respawn attempt bursts. ๐ธ--idiotโ Idiot mode (trust root with the above). ๐-f,--foregroundโ Run the client in the foreground. ๐ซถ-p,--pty[=noecho]โ Allocate a pseudo terminal for the client. ๐-B,--bindโ Stop when the user's last logind session ends. ๐-l,--errlog=specโ Send daemon's error output to syslog or file. ๐ญ-b,--dbglog=specโ Send daemon's debug output to syslog or file. ๐ฅ-o,--output=specโ Send client's output to syslog or file. ๐-O,--stdout=specโ Send client's stdout to syslog or file. โญ-E,--stderr=specโ Send client's stderr to syslog or file. ๐--ignore-eofโ AfterSIGCHLDignore any client output. ๐--read-eofโ AfterSIGCHLDread any client output (default). ๐--runningโ Check if a named daemon is running. ๐ง--restartโ Restart a named daemon client. ๐--stopโ Terminate a named daemon process. โจ--signal=signameโ Send a signal to a named daemon. ๐--listโ Print a list of named daemons. ๐
โจ DESCRIPTION โจ
Okay so daemon(1) turns other processes into daemons. There are, like, so many tasks that need to be performed to correctly set up a daemon process, and honestly? It can be tedious. daemon performs these tasks for other processes. ๐
The preparatory tasks that daemon performs for other processes are:
- First, revoke any setuid or setgid privileges that
daemonmay have been installed with โ by system administrators who laugh in the face of danger. ๐ - Process command line options.
- Change the root directory if the
--chrootoption was supplied. - Change the process uid and gid if the
--useroption was supplied. Only root can use this option. Note that the uid ofdaemonitself is changed, rather than just changing the uid of the client process. - Read the system configuration file(s) (
/etc/daemon.confand/etc/daemon.conf.d/*by default, or specified by the--configoption), unless the--noconfigoption was supplied. Then read the user's personal configuration file(s) (~/.daemonrcand~/.daemonrc.d/*), if any. Generic options that apply to all daemons are processed first, then options that are specific to the daemon with the given name. Note: The root directory and the user must be set before access to the configuration file(s) can be attempted, so neither the--chrootnor--useroptions may appear in the configuration file.
On BSD systems (except macOS), the system configuration file(s) are /usr/local/etc/daemon.conf and /usr/local/etc/daemon.conf.d/* by default.
On macOS, when installed via macports, the system configuration file(s) are /opt/local/etc/daemon.conf and /opt/local/etc/daemon.conf.d/*.
- Disable core file generation to prevent leaking potentially sensitive information in daemons that are run by root (unless the
--coreoption was supplied). - Become a daemon process:
- If
daemonwas not invoked byinit(8)(i.e. parent process id 1) orinetd(8)(i.e. stdin is a socket):- Ignore SIGHUP signals in case the current process session leader terminates while attached to a controlling terminal, causing us to receive a SIGHUP signal before we start our own process session below.
- If
This can happen when daemon was invoked interactively via the shell builtin exec. When this initial process terminates below, the terminal emulator that invoked the shell also terminates, so daemon need to protect itself from that.
- Background the process to lose process group leadership.
- Start a new process session.
- Background the process again to lose process session leadership. Under SVR4, this prevents the process from ever gaining a controlling terminal. This is only necessary under SVR4, but is always done for simplicity. Note that ignoring SIGHUP signals earlier means that when the newly created process session leader terminates, then even if it has a controlling terminal open, the newly backgrounded process won't receive the corresponding SIGHUP signal that is sent to all processes in the process session's foreground process group, because it inherited signal dispositions from the initial process.
- Change the current directory to the root directory so as not to hamper umounts.
- Clear the umask to enable explicit file creation modes.
- Close all open file descriptors. If
daemonwas invoked byinetd(8), stdin, stdout and stderr are left open, because they are open to a socket. - Open stdin, stdout and stderr to
/dev/null, in case something requires them to be open. Of course, this is not done ifdaemonwas invoked byinetd(8). - If the
--nameoption was supplied, create and lock a file containing the process id of the daemon process. The presence of this locked file prevents two instances of a daemon with the same name from running at the same time. The default location of the pidfile is/var/runfor root (/etcon Solaris,/opt/local/var/runon macOS when installed via macports), and/tmpfor normal users. If the--pidfilesoption was supplied, its argument specifies the directory in which the pidfile will be placed. If the--pidfileoption was supplied, its argument specifies the name of the pidfile and the directory in which it will be placed.
- If the
--umaskoption was supplied, set the umask to its argument, which must be a valid three-digit octal mode. Otherwise, set the umask to022, to prevent clients from accidentally creating group- or world-writable files. - Set the current directory if the
--chdiroption was supplied. - Spawn the client command and wait for it to terminate. The client command can be specified as command line arguments, or as the argument of the
--commandoption. If both the--commandoption and command line arguments are present, the client command is the result of appending the command line arguments to the argument of the--commandoption. - If the
--output,--stdoutand/or--stderroptions were supplied, the client's standard output and/or standard error are captured bydaemon, and are sent to the respective syslog destinations. - When the client terminates,
daemonrespawns it if the--respawnoption was supplied. If the client ran for less than 300 seconds (or the value of the--acceptableoption), thendaemonsees this as a failure. It will attempt to restart the client up to five times (or the value of the--attemptsoption), before waiting for 300 seconds (or the value of the--delayoption). This gives the system administrator the chance to correct whatever is preventing the client from running successfully without overloading system resources. If the--limitoption was supplied,daemonterminates after the specified number of respawn attempt bursts. The default is zero, which means never give up, never surrender.
When the client terminates, and the --respawn option wasn't supplied, daemon terminates as well.
- If
daemonreceives a SIGTERM signal (e.g. from a separate invocation ofdaemonwith the--stopoption), it propagates the signal to the client and then terminates. - If
daemonreceives a SIGUSR1 signal (from a separate invocation ofdaemonwith the--restartoption), it sends a SIGTERM signal to the client. If it was started with the--respawnoption, the client process will be restarted after it is terminated by the SIGTERM signal. - If the
--foregroundoption was supplied, the client process is run as a foreground process, and is not turned into a daemon at all. Ifdaemonis connected to a terminal, then the client process will also be connected to it. Ifdaemonis not connected to a terminal, but the client needs to be connected to a terminal, use the--ptyoption.
๐ OPTIONS ๐
-h,--helpโ Display a help message and exit. It just tells you how to use it and dips. โจ-V,--versionโ Display a version message and exit. Show me the numberrrr. ๐-v[level],--verbose[=level]โ Set the message verbosity level to level (or1if level is not supplied). This only effects the--runningand--listoptions. ๐-d[level],--debug[=level]โ bestie, this sets the debug message level to level (or1if level isn't supplied). ๐
Level 1 traces high-level function calls. Level 2 traces lower-level function calls and shows configuration information. Level 3 adds environment variables. Level 9 adds every return value from select(2). Debug messages are sent to the destination specified by the --dbglog option (by default, the syslog(3) facility, daemon.debug). โจ
-C path,--config=pathโ pick the system configuration file to use. By default,/etc/daemon.confis the system configuration file, if it exists and is not group- or world-writable, and does not exist in a group- or world-writable directory. The configuration file lets you predefine options that apply to all clients, and to specifically named clients. ๐
As well as the system configuration file, additional configuration files will be read from the directory whose path matches the system configuration file with .d appended to it (e.g. /etc/daemon.conf.d). Any file in that directory whose name starts with a dot character (.) is ignored. The same checks as described above apply to these files as well. ๐ฆ
On BSD systems (except macOS), the system configuration file(s) are /usr/local/etc/daemon.conf and /usr/local/etc/daemon.conf.d/* by default. ๐ธ
On macOS, when installed via macports, the system configuration file(s) are /opt/local/etc/daemon.conf and /opt/local/etc/daemon.conf.d/*. ๐
-N,--noconfigโ bypass the system configuration files,/etc/daemon.confand/etc/daemon.conf.d/*. Only the user's~/.daemonrcand~/.daemonrc.d/*configuration files will be read (if they exist). ๐-n name,--name=nameโ create and lock a pidfile (name.pid), ensuring that only one daemon with the given name is active at the same time. The standard location of the pidfile is/var/runfor root (/etcon Solaris,/opt/local/var/runon macOS when installed via macports), and/tmpfor normal users. This location can be overridden with the--pidfilesoption. ๐
The name may only consist of the following characters:
-._abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
While a named daemon's client process is running, there will also be a separate pidfile to record the process id of the client process. Its filename will be the same as the daemon pidfile's, except that the filename extension will be .clientpid rather than .pid. The only reason that there should be a .pid file, with no .clientpid file, is during the delay between respawn attempts bursts. ๐ญ
-X "cmd",--command="cmd"โ specify the client command as an option. If a command is specified along with its name in the configuration file, then a daemon can be invoked merely by mentioning its name:
daemon --name ftumch
Note: If the client command is specified with the --command option, either in the configuration file, or on the command line, then any additional command line arguments on the daemon command line are appended to the client command that is specified with the --command option. ๐
-P /dir,--pidfiles=/dirโ override the standard pidfile location. The standard pidfile location is/var/runfor root (/etcon Solaris,/opt/local/var/runon macOS when installed via macports), and/tmpfor normal users. ๐
This option only affects the --name and --list options. Use this option if these standard locations are unacceptable, but make sure that you don't forget where you put your pidfiles. This option is best used in configuration files, or in shell scripts, rather than on an interactive command line. ๐ซถ
The pidfile location will be created automatically only if it is within the user's home directory. ๐
-F /path,--pidfile=/pathโ override the standard pidfile name and location. The standard pidfile location is described immediately above. The standard pidfile name is the argument of the--nameoption followed by.pid. Use this option if the standard pidfile name and location are unacceptable, but make sure that you don't forget where you put your pidfile. This option is best used in configuration files, or in shell scripts, rather than on an interactive command line. โจ
The pidfile location will be created automatically only if it is within the user's home directory. ๐
-u user[:[group]],--user=user[:[group]]โ run the client as a different user (and group). This only works for root. If the argument includes a:groupspecifier, daemon will assume the specified group and no other. Otherwise, daemon will assume all groups that the specified user is in. For backwards compatibility,.may be used instead of:to separate the user and group but since.can appear in user and group names, ambiguities can arise such as using--user=u.gwhen usersuandu.gand groupgall exist. With such an ambiguity, daemon will assume the useruand groupg. Use--user=u.g:instead for the other interpretation. ๐-R path,--chroot=pathโ change the root directory to path before running the client. On some systems, only root can do this. Note that the path to the client program and to the configuration file (if any) must be relative to the new root path. ๐ฆ-D path,--chdir=pathโ change the current directory to path before running the client. The default current directory is the root directory (possibly after chroot). ๐ธ-m umask,--umask=umaskโ change the umask to umask before running the client. umask must be a valid octal mode. The default umask is022. ๐-e "var=val",--env="var=val"โ set an environment variable for the client process. This option can be used any number of times. If it is used, only the supplied environment variables are passed to the client process. Otherwise, the client process inherits the current set of environment variables. ๐-i,--inheritโ explicitly inherit environment variables. This is only needed when the--envoption is used. When this option is used, the--envoption adds to the inherited environment, rather than replacing it. ๐-U,--unsafeโ allow reading an unsafe configuration file, and allow the execution of an unsafe executable. A configuration file or executable is considered to be unsafe if it is group- or world-writable or is in a directory that is group- or world-writable (following symbolic links). If an executable is a script that is interpreted by another executable, then it is considered to be unsafe if the interpreter is unsafe. If the interpreter is/usr/bin/env(with an argument that is a command name to be searched for in$PATH), then that command must be safe. By default,daemon(1)will refuse to read an unsafe configuration file or to execute an unsafe executable when run by root. This option overrides that behaviour and hence should never be used. ๐
Bestie, this overrides the safety and hence should NEVER be used. ๐
-S,--safeโ disallow reading an unsafe configuration file, and disallow the execution of an unsafe executable. By default,daemon(1)will allow reading an unsafe configuration file, and allow the execution of an unsafe executable, when run by normal users. This option overrides that behaviour. ๐ซถ-c,--coreโ allow the client to create a core file. This should only be used for debugging, as it could lead to security-related information disclosures by daemons run by root. ๐--nocoreโ by default, clients are prevented from creating a core file. If the--coreoption has been used in a configuration file to apply to all named daemons, then this option can be used to restore the default behaviour for specific named daemons. โจ-r,--respawnโ respawn the client when it terminates. Without this option, the termination of a client process causes daemon itself to terminate as well. ๐ฅ-a #,--acceptable=#โ specify the minimum acceptable duration of a client process, in seconds. This option can only be used with the--respawnoption. If a client process terminates before this threshold is reached, then it is considered to have failed. The default value is300seconds. It cannot be set to less than10seconds, except by root when used in conjunction with the--idiotoption. ๐-A #,--attempts=#โ specify the number of attempts to respawn before delaying. This option can only be used with the--respawnoption. The default value is5. It cannot be set to more than100attempts, except by root when used in conjunction with the--idiotoption. ๐ธ-L #,--delay=#โ specify the delay in seconds between each burst of respawn attempts. This option can only be used with the--respawnoption. The default value is300seconds. It cannot be set to less than10seconds except by root when used in conjunction with the--idiotoption. ๐ฆ-M #,--limit=#โ specify a limit to the number of respawn attempt bursts. This option can only be used with the--respawnoption. The default value is0, which means no limit. ๐--idiotโ turn on idiot mode in which daemon will not enforce the minimum or maximum values normally imposed on the--acceptable,--attemptsand--delayoptions. The--idiotoption must appear before any of these options. Only the root user may use this option, because it can turn a slight misconfiguration into a lot of wasted CPU energy and log messages, somewhat akin to a self-inflicted denial of service. ๐
Idiot mode also allows the root user to expand environment variable notation (e.g. $VAR and ${VAR}) in command line option arguments, and in configuration files. By default, internal environment variable expansion is only performed for normal users. Note that this doesn't apply to any such expansion performed earlier by the shell that invokes daemon(1). See the EXPANSION section below for more details. ๐
-f,--foregroundโ run the client in the foreground. The client is not turned into a daemon. โจ-p[noecho],--pty[=noecho]โ connect the client to a pseudo terminal. This option can only be used with the--foregroundoption. This is the default when the--foregroundoption is supplied and daemon's standard input is connected to a terminal. This option is only necessary when the client process must be connected to a controlling terminal, but daemon itself has been run without a controlling terminal (e.g. fromcron(8)or a pipeline). ๐
If the noecho argument is supplied along with this option, the client's side of the pseudo terminal gets flipped into noecho mode ๐ only do this if there's actually a terminal involved and the input is being echoed twice, bestie.
-B,--bindโ auto-yeets the client process (anddaemon(1)itself, both of them, together, iconic) the absolute second the user has nosystemd-logind(8)(orelogind(8)) user sessions left. Translation: it kills everything when the user logs out ๐ซถ. And if the user had no sessions to begin with? Then the client process gets terminated immediately. No thoughts, just goodbye.
This one is only available on Linux systems that have either systemd(1) (hi Debian) or elogind(8) (hi Slackware). On systems with systemd(1), you could lowkey just use a systemd user service instead, especially if your user account isn't allowed to have user services that linger ๐.
-lspec,--errlog=spec โ sends daemon's standard output and standard error to whichever syslog destination or file spec names ๐ธ. If spec is a syslog destination shaped like"facility.priority", the output goes tosyslog(3). Otherwise the output gets appended to the file at the path given in spec. Default vibe: output goes to the syslog destinationdaemon.err. More deets down in the MESSAGING section ๐.-bspec,--dbglog=spec โ sends daemon's debug output to the syslog destination or file given by spec โจ. If spec looks like"facility.priority", it goes tosyslog(3); otherwise it's appended to the file at that path. Default: syslog destinationdaemon.debug. Again, see MESSAGING below ๐.-ospec,--output=spec โ captures the client's standard output and standard error and sends them to the syslog destination or file in spec ๐ฆ."facility.priority"-shaped spec meanssyslog(3), anything else means append to that file path. By default, output is discarded โ unless you've got--foregroundon, in which case the client's stdout and stderr get propagated to daemon's stdout and stderr respectively. MESSAGING section, go read it ๐.-Ospec,--stdout=spec โ captures the client's standard output and sends it to the syslog destination or file named by spec ๐."facility.priority"style โsyslog(3). Otherwise stdout is appended to the file at that path. Default: stdout is discarded, unless--foregroundis present, in which case the client's stdout is propagated to daemon's stdout. You already know where to look for more โ MESSAGING ๐.-Espec,--stderr=spec โ captures the client's standard error and sends it to the syslog destination or file given in spec ๐ญ."facility.priority"-shaped โsyslog(3). Otherwise stderr is appended to that file path. Default: stderr is discarded, unless--foregroundis present, in which case the client's stderr is propagated to daemon's stderr. Yes bestie, the MESSAGING section has more ๐.--ignore-eofโ so after it gets aSIGCHLDsignal because a client process stopped or restarted, it does not bother reading the client's output until end-of-file before reaping the client's termination status withwait(2)๐. Normally there's little to no output after thatSIGCHLDโ the client process just terminated, slay โ but the client process might have its own child processes keeping its output open long after it died. When that happens, by default the client process stays a zombie process ๐ until its children terminate and close the output. Waiting for the client's children to terminate before considering the client stopped (and before restarting a fresh invocation) might be what you want. If it's not, this option lets you treat the client process as terminated the moment theSIGCHLDarrives and reap its termination status withwait(2)right away โญ.--read-eofโ the opposite energy: after aSIGCHLDsignal from a stopped or restarted client process, it keeps reading the client's output until end-of-file before reaping the client's termination status withwait(2)๐ง. This is the default behaviour, no cap. Same deal as above: usually barely any output post-SIGCHLDsince the client just terminated, but the client might have its own child processes keeping output open long after. When that happens, the client process remains a zombie ๐ until its children terminate and close the output. Waiting for those children before considering the client stopped (and before restarting a new invocation) might be desirable. So if--ignore-eofwas set in a configuration file and it applies to all named daemons, this option restores the default behaviour for specific named daemons ๐.--runningโ checks whether a named daemon is running, thenexit(3)s withEXIT_SUCCESSif it is, orEXIT_FAILUREif it isn't โจ.
With --verbose it prints a message before exiting ๐. If both the named daemon and its client process are running, the output looks like this, showing both process IDs:
daemon: name is running (pid 7455) (clientpid 7457)
If the named daemon is running but its client process isn't (there might be a delay between respawn attempt bursts), you get this, with only the daemon process's ID:
daemon: name is running (pid 7455) (client is not running)
And if the named daemon isn't running at all, you get:
daemon: name is not running
โ ๏ธ This option can only be used with the--nameoption. Also note that the--chroot,--user,--name,--pidfilesand--pidfile(and possibly--config) options must be the same as for the target daemon, or it won't vibe check correctly ๐.
--restartโ tells a named daemon to terminate and restart its client process by sending it aSIGUSR1signal ๐ฅ. The named daemon then sends its client process aSIGTERMto stop it. If that named daemon was originally started with the--restartoption, it'll restart the client process. If not, this does the exact same thing as--stopโ and the client process does not come back ๐ญ.
โ ๏ธ Only usable with--name. And again:--chroot,--user,--name,--pidfilesand--pidfile(and possibly--config) must match the target daemon ๐ .
--stopโ stops a named daemon by sending it aSIGTERMsignal ๐. That makes the named daemon send its client process aSIGTERMoption and then exit. (Yes, bestie, the manpage literally says "aSIGTERMoption" โ we're keeping it exactly as written, character for character ๐ซถ.)
โ ๏ธ Only usable with--name. Same rules, same list, same must-match energy:--chroot,--user,--name,--pidfilesand--pidfile(and possibly--config) ๐.
--signal=signame โ sends the given signal to a named daemon's client process ๐ธ. You can specify the signal by number or by name (with or without the"sig"prefix ๐). Any signal may be sent โ but heads up, the client process might be ignoring some of them. For example,SIGHUPis ignored by default unless the client process has installed a signal handler for it ๐.
The known list of signals is: hup, int, quit, ill, trap, abrt, iot, bus, fpe, kill, usr1, segv, usr2, pipe, alrm, term, stkflt, cld, chld, cont, stop, tstp, ttin, ttou, urg, xcpu, xfsz, vtalrm, prof, winch, poll, io, pwr, sys, emt and info. Not all of them are available on all platforms ๐ฆ.
--listโ prints a list of the currently running named daemons whose pidfiles live in the applicable pidfile directory ๐. That directory is either the default โ/var/runfor root (/etcon Solaris,/opt/local/var/runon macOS when installed via macports), and/tmpfor normal users โ or whatever you set with the--pidfilesoption. Then it exits โจ.
Without --verbose, this only lists the names of daemons whose pidfiles are locked, since locked implies the corresponding daemon must still be running ๐. Careful though: pidfiles for daemons that were not started by daemon(1) might not be locked. An unlocked pidfile might mean daemon(1) died unexpectedly ๐ฑ, or it might just be a pidfile for a daemon that wasn't started by daemon(1). If that's gonna be confusing, consider using a dedicated pidfiles directory for named daemons started by daemon(1) and leaving the default pidfiles directories for other daemons started independently of daemon(1) ๐
.
With --verbose, the items in the list look like the output of --running with --verbose, but with more detail ๐.
If there are no pidfiles at all, the output looks like this:
No named daemons are running
If a pidfile is locked and there's a corresponding client pidfile, that means the named daemon and its client are both running โ output shows both process IDs:
name is running (pid ####) (client pid ####)
If a pidfile is locked but there's no client pidfile, the named daemon is running while its client isn't (e.g. during a delay between respawn attempt bursts when the client keeps failing to start successfully ๐ญ). The output will be one of these three options:
When we can tell the pidfile belongs to a process whose executable name is daemon:
name is running (pid ####) (client is not running)
When we can tell the pidfile belongs to a process whose executable name is something other than daemon (i.e. it's independent of daemon(1)):
name is running (pid ####) (independent)
And when it's just not possible to determine the name of the executable associated with the pidfile (i.e. on systems other than Linux without a /proc file system ๐):
name is running (pid ####) (client is not running or is independent)
Okay so continuing where we left off, bestie ๐ โ remember this next bit is all about what happens when that pidfile situation is not on lock:
If a pidfile isn't locked, and the pidfiles directory in play is the default one, that basically means one of two things: either your daemon ๐d unexpectedly, or the pidfile belongs to a daemon that was never started by daemon(1) in the first place. Either way, the output is gonna look exactly like this:
name is not running (or is independent)
But if the pidfile isn't locked and the pidfiles directory isn't the default? Then it's just assumed that literally every pidfile is for a daemon that daemon(1) started, and the output looks like this instead:
name is not running
And like with literally every other program on the planet, a -- argument means "okay options are DONE." Anything appearing on the command line after -- is part of the client command. that's it, that's the rule ๐ซถ
โจ EXPANSION โจ
So daemon does a lil bit of simple shell-like expansion internally, and it only happens on the arguments of the command line options that take a text argument. The options with a numeric argument? Nope, they don't get any of this. ๐
Here's the order:
- Environment variable notation, like
$VARor${VAR}โ expanded. โ - Then user home directory notation, like
~or~userโ expanded. โ - File name expansion (aka globbing)? NOT performed internally. And neither are any of your login shell's other ~wonderful~ expansions. This is very basic, okay? like, keep your expectations low ๐ง
Honestly this might not be super useful on the command line, because daemon usually gets invoked through a shell, and the shell already did all its usual expansions first. It might even be undesirable to expand internally after the shell already did โ like if you're referencing directory names that literally contain a $ character, or you're using environment variables whose values contain a $ character (which, lowkey, is unlikely).
But it can be useful in configuration files. Peep the FILES section below for the deets ๐ It can also come in clutch when daemon gets invoked directly by another program, with no shell in the mix.
By default, environment variable expansion is not performed for the root user โ even if the environment variable was defined in the configuration files. The --idiot option can change that behaviour and let environment variables expand for the root user. Home directory notation expansion, though? That happens for everybody. all users, no exceptions ๐
๐ FILES ๐
/etc/daemon.conf,/etc/daemon.conf.d/*โ system-wide default options/usr/local/etc/daemon.conf,/usr/local/etc/daemon.conf.d/*โ system-wide default options on BSD systems (except macOS)./opt/local/etc/daemon.conf,/opt/local/etc/daemon.conf.d/*โ system-wide default options on macOS when installed via macports.~/.daemonrc,~/.daemonrc.d/*โ user-specific default options
Every single line of the configuration file is either an environment variable definition or a configuration directive. no in-between, that's the whole vibe ๐ธ
๐ Environment variable definitions
These are the variable name, followed immediately by = and then the value of the variable. They look like they do in shell, except there's no quoting or other shell syntax. Environment variable values can include simple environment variable notation (like $VAR or ${VAR}) and user home directory notation (like ~ or ~user). All of that gets expanded internally by daemon. Go back up to the EXPANSION section if you need the refresher โจ
โ ๏ธ Watch out bestie: any environment variables defined in the configuration file that then get used explicitly in another environment variable definition, or in an option argument, will have those expansions performed multiple times. So avoid environment variables whose values can change again if expansion runs multiple times. fr fr.
Example:
PATH=/usr/bin:/usr/sbin:$HOME/bin:~app/bin
PIDFILES=~/.run
๐ Configuration directives
A configuration directive is a client name (for options that apply to a single client) or * (for generic options that apply to all clients), then spaces and/or tabs, then a comma-separated list of options. Heads up: any option arguments must not contain any commas. The commas that separate options can have spaces and tabs before and after them, so breathe, it's fine. Option arguments that are text (but not numbers) can include simple environment variable notation (like $VAR or ${VAR}) and user home directory notation (like ~ or ~user). These ge expanded internally by daemon too โ again, see EXPANSION above ๐
Blank lines and comments (# to the end of the line) are ignored. And lines can be continued with a \ character at the end of the line. cute, right?
Example:
* errlog=daemon.err,output=local0.err,core
test1 syslog=local0.debug,debug=9,verbose=9,respawn
test2 syslog=local0.debug,debug=9, \
verbose=9,respawn, \
pidfiles=$PIDFILES
๐ The order of operations (iconic behaviour, honestly)
The command line options get processed first, to look for a --config option. If no --config option was supplied, then the default configuration files are used: /etc/daemon.conf and /etc/daemon.conf.d/*. On BSD systems (except macOS), the default configuration files are /usr/local/etc/daemon.conf and /usr/local/etc/daemon.conf.d/*. On macOS when installed via macports, the default configuration files are /opt/local/etc/daemon.conf and /opt/local/etc/daemon.conf.d/*. And if the user has their own configuration files, ~/.daemonrc and ~/.daemonrc.d/*, those get used too ๐
If the configuration files contain any generic (*) entries, their options are applied in order of appearance. If the --name option was supplied, and the configuration files contain any entries for the given name, those options are then applied in order of appearance.
Finally, the command line options get applied again. Why? Because this makes sure any generic options apply to all clients by default. And the hierarchy is very slay:
- Client-specific options override generic options.
- User options override system-wide options.
- Command line options override everything else. periodt ๐
๐จ Big note: the configuration files are not opened and read until after any--chrootand/or--usercommand line options are processed. This means a few things: - The configuration file paths and the client's file path must be relative to the--chrootargument. - The configuration files and the client executable must be readable/executable by the user specified by the--userargument. - The--chrootand--useroptions must not appear in the configuration file. - Also, the--nameoption must not appear on the right hand side in the configuration file either.
๐ MESSAGING ๐
The --errlog, --dbglog, --output, --stdout and --stderr options all take an argument that can be either a syslog destination of the form "facility.priority", or the path to a file. Here are the lists, bestie, memorize them or don't, I'm not your mom ๐
Facilities:
kern, user, mail, daemon, auth, syslog, lpr, news, uucp, cron,
local0, local1, local2, local3, local4, local5, local6, local7.
Priorities:
emerg, alert, crit, err, warning, notice (on some systems), info, debug.
If you supply the path to a file instead, remember that daemon(1) changes to the root directory by default, so that file path should be an absolute path (or relative to the --chroot and/or --chdir option argument). Otherwise daemon(1) will attempt to create the file relative to its current directory. And you might not have permissions to do that โ or want to even if you do. ๐ญ
๐ CAVEAT ๐
Clients can only be restarted if they were started with the --respawn option. Using --restart on a non-respawning daemon client is equivalent to using --stop. So if you try to restart a named daemon and it justโฆ stops instead? Yeah, it probably wasn't started with the --respawn option. mystery solved ๐ฅ
Clients that are run in the foreground with a pseudo terminal don't respond to job control (i.e. suspending with Ctrl+Z doesn't work). Why? Because the client belongs to an orphaned process group (it starts in its own process session), so the kernel won't send it SIGSTOP signals. That's just how it is. However, if the client is a shell that supports job control, then its subprocesses can be suspended. so there's that ๐ฆ
In KDE, if you use "exec daemon" (or just "exec" without daemon) in a shell to run a KDE application, you might find that the KDE application sometimes doesn't run. This problem has only been seen with konsole(1), but it might happen with other KDE applications as well. Capturing the standard error of the KDE application might show something like:
unnamed app(9697): KUniqueApplication: Registering failed!
unnamed app(9697): Communication problem with "konsole" , it probably crashed.
Error message was: "org.freedesktop.DBus.Error.ServiceUnknown" : " "The name
org.kde.konsole was not provided by any .service files"
A workaround seems to be to delay the termination of the initial daemon(1) process by at least 0.4 seconds. To make that happen, set the environment variable DAEMON_INIT_EXIT_DELAY_MSEC to the number of milliseconds by which to delay. Example: DAEMON_INIT_EXIT_DELAY_MSEC=400. Or you could just avoid using exec when starting KDE applications. your call bestie ๐
On Linux systems that have systemd(1) or elogind(8), you might find that your daemon processes and their client processes are terminated when you logout โ even though they're in a different process session and so should be unaffected. Rude, I know. This is because systemd has the ability to terminate all of your processes when you logout. Luckily, this feature is turned off by default in some Linux distributions. However, if it is on, you can turn it off by adding this exact line to /etc/systemd/logind.conf (or /etc/elogind/logind.conf):
KillUserProcesses=no
โญ SEE ALSO โญ
libslack(3), daemon(3), coproc(3), pseudo(3), init(8), inetd(8), fork(2), umask(2), setsid(2), chdir(2), chroot(2), setrlimit(2), setgid(2), setuid(2), setgroups(2), initgroups(3), syslog(3), kill(2), wait(2), systemd-logind(8), elogind(8)
๐ AUTHOR ๐
20230824 raf <raf@raf.org>
And that's a wrap on the whole page, bestie ๐ this was daemon-0.8.4, dated 20230824. go forth and daemonize responsibly, you absolute main character ๐โจ
๐ฆ where this page comes from
- ubuntu resolute: daemon 0.8.4-1build1 ยท GPL-2.0-or-later
- ubuntu stonking: daemon 0.8.4-1build1 ยท GPL-2.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms