SYSTEMD.PATH(5)

๐Ÿ’… SYSTEMD.PATH(5) โ€” the systemd.path manual, bestie edition โœจ

okay so you're here for systemd.path and honestly? iconic of you. this is the Path unit configuration page. let's get into it ๐Ÿซถ


๐ŸŒธ SYNOPSIS ๐ŸŒธ

path.path

โœจ DESCRIPTION โœจ

so a unit configuration file whose name ends in .path is out here encoding info about a path that systemd is monitoring โ€” that's what we call path-based activation, and it's giving main character energy fr fr.

this page lists the config options that are specific to this unit type, okay? for the common options that every unit config file gets, go read systemd.unit(5). those shared bits live in the generic [Unit] and [Install] sections. the path-specific stuff? that goes in the [Path] section. no cap.

for every path file, a matching unit file must exist โ€” that's the unit that gets activated when the path changes. by default, it's a service with the same name as the path (minus the suffix) that gets activated. example time: a path file foo.path activates the matching service foo.service ๐ŸŽ€. you can control which unit gets activated with Unit= (more on that below ๐Ÿ‘‡).

internally, path units use the inotify(7) API to monitor file systems. and because of that, it suffers the same limitations as inotify โ€” for example, it literally cannot be used to monitor files or directories changed by other machines on remote NFS file systems. so don't try it, bestie ๐Ÿ’€.

here's the tea on the loop situation โ˜•: when a service unit triggered by a path unit terminates (and honestly, doesn't matter whether it exited successfully or failed), the monitored paths get checked immediately again, and the service gets restarted instantly. and because we are NOT about to busy-loop in this trigger/start cycle, a start rate limit is enforced on the service unit โ€” peep StartLimitIntervalSec= and StartLimitBurst= in systemd.unit(5). but here's the plot twist: unlike other service failures, when the start rate limit gets hit, that error condition propagates from the service unit to the path unit, which makes the path unit fail as well, thus ending the loop. the drama. the resolution. we love a clean exit ๐Ÿ‘‘


๐Ÿ”— AUTOMATIC DEPENDENCIES ๐Ÿ”—

Implicit Dependencies ๐Ÿ’ซ

these dependencies get added implicitly, no asking:

  • if a path unit is beneath another mount unit in the file system hierarchy, both a requirement and an ordering dependency between both units are created automatically. automatic. slay.
  • an implicit Before= dependency is added between a path unit and the unit it's supposed to activate.

Default Dependencies ๐ŸŒˆ

these get added unless DefaultDependencies=no is set:

  • path units will automatically have dependencies of type Before= on paths.target, dependencies of type After= and Requires= on sysinit.target, and have dependencies of type Conflicts= and Before= on shutdown.target. all of this ensures path units are terminated cleanly prior to system shutdown ๐Ÿงน. only path units involved with early boot or late system shutdown should disable the DefaultDependencies= option. everyone else, leave it alone ๐Ÿ’œ

๐Ÿ‘‘ OPTIONS ๐Ÿ‘‘

path unit files may include [Unit] and [Install] sections, which are described in systemd.unit(5).

path unit files must include a [Path] section, which carries information about the path or paths it monitors. the options specific to the [Path] section of path units are the following:

  • PathExists=, PathExistsGlob=, PathChanged=, PathModified=, DirectoryNotEmpty= โ€” defines paths to monitor for certain changes. let's break it down:
    • PathExists= may be used to watch the mere existence of a file or directory. if the file specified exists, the configured unit is activated โœจ.
    • PathExistsGlob= works similarly, but checks for the existence of at least one file matching the globbing pattern specified.
    • PathChanged= may be used to watch a file or directory and activate the configured unit whenever it changes. it is not activated on every write to the watched file, but it is activated if the file which was open for writing gets closed.
    • PathModified= is similar, but additionally it is activated also on simple writes to the watched file.
    • DirectoryNotEmpty= may be used to watch a directory and activate the configured unit whenever it contains at least one file.

the arguments of these directives must be absolute file system paths ๐Ÿšจ.

multiple directives may be combined โ€” of the same type and of different types โ€” to watch multiple paths. if the empty string is assigned to any of these options, the list of paths to watch is reset, and any prior assignments of these options will not have any effect. clean slate, periodt.

if a path already exists (in the case of PathExists= and PathExistsGlob=) or a directory already is not empty (in the case of DirectoryNotEmpty=) at the time the path unit is activated, then the configured unit is immediately activated as well. something similar does not apply to PathChanged= and PathModified= ๐Ÿ™ˆ.

if the path itself or any of the containing directories are not accessible, systemd will watch for permission changes and notice that conditions are satisfied when permissions allow that. it's patient like that ๐Ÿงš.

note that files whose name starts with a dot (i.e. hidden files) are generally ignored when monitoring these paths. yes, the sneaky ones. they're invisible to this ๐Ÿ‘€
  • Unit= โ€” the unit to activate when any of the configured paths changes. the argument is a unit name, whose suffix is not .path. if not specified, this value defaults to a service that has the same name as the path unit, except for the suffix (see above ๐Ÿ’). it is recommended that the unit name that is activated and the unit name of the path unit are named identical, except for the suffix. matching names, matching vibes ๐Ÿ’–.
  • MakeDirectory= โ€” takes a boolean argument. if true, the directories to watch are created before watching. this option is ignored for PathExists= settings. defaults to false.
  • DirectoryMode= โ€” if MakeDirectory= is enabled, use the mode specified here to create the directories in question. takes an access mode in octal notation. defaults to 0755.
  • TriggerLimitIntervalSec=, TriggerLimitBurst= โ€” configures a limit on how often this path unit may be activated within a specific time interval. the TriggerLimitIntervalSec= may be used to configure the length of the time interval in the usual time units "us", "ms", "s", "min", "h", ... and defaults to 2s. see systemd.time(7) for details on the various time units understood. the TriggerLimitBurst= setting takes a positive integer value and specifies the number of permitted activations per time interval, and defaults to 200. set either to 0 to disable any form of trigger rate limiting. if the limit is hit, the unit is placed into a failure mode, and will not watch the paths anymore until restarted ๐Ÿ˜ญ. note that this limit is enforced before the service activation is enqueued.

added in version 250.

check systemd.unit(5), systemd.exec(5), and systemd.kill(5) for more settings ๐Ÿซถ.


๐Ÿฆ‹ SEE ALSO ๐Ÿฆ‹

environment variables with details on the trigger will be set for triggered units. see the section "Environment Variables Set or Propagated by the Service Manager" in systemd.exec(5) for more details.

systemd(1), systemctl(1), systemd.unit(5), systemd.service(5), inotify(7), systemd.directives(7)


and that's the whole page, bestie ๐Ÿ’… this was systemd 262.1, and yeah โ€” you read the whole thing, which is honestly so iconic of you. go watch some paths. go activate some units. i'm obsessed ๐ŸŒŸ๐Ÿ’–

๐Ÿ“ฆ where this page comes from
  • arch rolling: systemd 262.1-1 ยท LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later AND MIT-0
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms