SYSTEMD-NOTIFY(1)
๐ธ SYSTEMD-NOTIFY(1) ๐ธ
okay bestie, welcome to systemd-notify, section 1 of the manuals. pull up a chair, grab a boba, this one's lowkey a banger ๐
โจ NAME โจ
systemd-notify โ notify the service manager that your service finished starting up, plus whatever other daemon status glow-ups you wanna announce ๐ฆ
๐ SYNOPSIS ๐
systemd-notify [OPTIONS...] [VARIABLE=VALUE...]
systemd-notify --exec [OPTIONS...] [VARIABLE=VALUE...] ; -- {CMDLINE...}
systemd-notify --fork [OPTIONS...] -- {CMDLINE...}
๐ DESCRIPTION ๐
so, systemd-notify is the little messenger your service scripts call when they wanna tell the service manager that things changed. it can send literally any information you want, encoded as a list of strings that's shaped just like an environment block. but the main character use case? telling everyone the service finished starting up. that's the moment. that's the vibe. ๐
fr fr, this thing is mostly just a wrapper around sd_notify() so that shell scripts can get in on the fun. want the full tea? go read sd_notify(3).
your command line can carry a whole list of environment variables, and those get sent along as part of the status update. slay.
โ ๏ธ heads up bestie: systemd will straight-up refuse your status updates unlessNotifyAccess=is set appropriately for the service unit you're calling this from. no cap. checksystemd.service(5)for the details.
okay this next part is important so listen up ๐ซถ. sd_notify() notifications only get attributed to units correctly if either:
- the sending process is still around at the time the service manager processes the message, or
- the sending process is explicitly runtime-tracked by the service manager.
that second one happens when the service manager originally forked off the process โ i.e. it applies to all processes that match NotifyAccess=main or NotifyAccess=exec. but flip it around: if some auxiliary process of the unit sends an sd_notify() message and then immediately dips out, the service manager might not be able to attribute that message to the unit properly, and so it'll just ignore it โ even if NotifyAccess=all is set for it. ๐
to fix that whole situation, systemd-notify will wait until the notification message has actually been processed by the service manager. but when --no-block is used, that synchronization for reception of notifications gets disabled, which means the race condition above may absolutely happen if the invoking process is not the service manager or wasn't spawned by the service manager. yikes.
here's the other cute trick: systemd-notify will first attempt to invoke sd_notify() while pretending to have the PID of the parent process of systemd-notify โ that's the invoking process, hi. this only succeeds when you invoke it with sufficient privileges. if it fails, it falls back to invoking under its own PID. why does this matter? because when the tool gets invoked from a shell script, the shell process โ not the systemd-notify process โ shows up as the sender of the message. and that's super helpful if the shell process is the main process of a service, because of the limitations of NotifyAccess=all. wanna tweak this behaviour? use the --pid= switch. โจ
๐ OPTIONS ๐
here's everything you can pass, bestie. the following options are understood:
--readyโ tell the invoking service manager that service start-up (or a configuration reload) is complete. this is equivalent tosystemd-notify READY=1. for the full semantics of this option, seesd_notify(3). โ--reloadingโ tell the invoking service manager that a configuration reload cycle is beginning. equivalent tosystemd-notify RELOADING=1โ but bestie, it implicitly also sets aMONOTONIC_USEC=field, as required forType=notify-reloadservices. seesystemd.service(5)for that. semantics deets insd_notify(3).
Added in version 253.
--stoppingโ tell the invoking service manager that the service is entering its shutdown phase. equivalent tosystemd-notify STOPPING=1. semantics deets insd_notify(3).
Added in version 253.
--pid=โ inform the service manager about the main PID of the service. takes a PID as its argument. if the argument is specified as"auto"or just omitted entirely, the PID of the process that invoked systemd-notify is used โ except if that's the service manager. if the argument is"self", the PID of the systemd-notify command itself is used. and if"parent"is specified, the calling process' PID is used โ even if it is the service manager.--pid=autois equivalent tosystemd-notify --pid=$PID. semantics deets insd_notify(3).
systemd-notify will first attempt to invoke sd_notify() pretending to have the PID you specified with --pid=. this only succeeds when invoked with sufficient privileges. on failure, it falls back to invoking it under its own PID. effectively, this means a privileged invocation of systemd-notify --pid= may circumvent NotifyAccess=main or NotifyAccess=exec restrictions that are enforced for a service. ๐
if this switch is used in an unprivileged systemd-notify invocation, from a process that's supposed to become the new main process of a service โ and which is not the process forked off by the service manager (or the current main process) โ then it is essential to setNotifyAccess=allin the service unit file. otherwise the notification will be ignored, for security reasons. seesystemd.service(5).
- *
--uid=USER* โ set the user ID to send the notification from. takes a UNIX user name or a numeric UID. when specified, the notification message gets sent with the specified UID as the sender, instead of the user the command was invoked as. this option requires sufficient privileges to be able to manipulate the user identity of the process.
Added in version 237.
--status=โ send a free-form, human-readable status string for the daemon to the service manager. this option takes the status string as its argument. equivalent tosystemd-notify STATUS=.... semantics deets insd_notify(3). this info shows up insystemctl(1)'s status output, among other places. ๐--bootedโ returns0if the system was booted up with systemd, and non-zero otherwise. if this option is passed, no message is sent. so yeah, this option is unrelated to all the other options. for semantics deets, seesd_booted(3). another way to check this state is to callsystemctl(1)with theis-system-runningcommand. it'll output"offline"if the system wasn't booted with systemd โ though ngl, the return value has a different meaning there.--no-blockโ do not synchronously wait for the requested operation to finish. this one's only recommended when systemd-notify is spawned by the service manager, or when the invoking process is directly spawned by the service manager and has enough privileges to let systemd-notify send the notification on its behalf. sending notifications with this option set is prone to race conditions in all other cases. ๐
Added in version 246.
--execโ if specified, systemd-notify will execute another command line after it completed its operation, replacing its own process. if you use this, the list of assignments to include in the message sent must be followed by a";"character (as a separate argument), followed by the command line to execute. this permits "chaining" of commands โ i.e. issuing one operation and then immediately another, without changing PIDs. iconic.
note that many shells interpret";"as their own separator for command lines, so when systemd-notify is invoked from a shell, the semicolon usually has to be escaped as"\;". ๐
Added in version 254.
--fd=โ send a file descriptor along with the notification message. super useful when invoked in services that have theFileDescriptorStoreMax=setting enabled โ seesystemd.service(5). the specified file descriptor must be passed to systemd-notify when invoked. this option may be used multiple times to pass multiple file descriptors in a single notification message.
to use this from a bash(1) shell, use an expression like this:
systemd-notify --fd=4 --fd=5 4</some/file 5</some/other/file
Added in version 254.
--fdname=โ set a name to assign to the file descriptors passed via--fd=(see above). this controls the"FDNAME="field. this setting may only be specified once, and it applies to all file descriptors passed. if you want multiple file descriptors with different file descriptor names, invoke this tool multiple times. ๐ฆ
Added in version 254.
--forkโ instead of sending a notification message, fork off a command line and wait until a"READY=1"message is received from it. in other words: this makes systemd-notify the receiver of notification messages instead of the sender, swapping roles. main character energy fr. this is useful to quickly fork off a process that implements thesd_notify()protocol from a shell script. the invoked command line will have standard input and standard output connected to/dev/null, but standard error will be inherited from the invoking process. the numeric process ID is written to standard output by systemd-notify (unless--quietis specified), which you may use to later terminate the forked off process.
note that processes forked off like this will likely remain running after systemd-notify already returned, which means they'll end up reparented to the closest process reaper โ typically the per-user or system service manager.
also note: this option should not be used to invoke full services ad-hoc. use systemd-run for that, bestie.
also note that when invoked with this switch, systemd-notify will exit successfully under two distinct conditions:
- systemd-notify received a
"READY=1"notification from the child it just forked off. - the child process exited cleanly (with exit status zero) before sending
"READY=1".
example use:
# PID=$(systemd-notify --fork -- mycommand)
...
kill "$PID"
unset PID
Added in version 258.
--quiet,-qโ turn off the output of the numeric process ID when--forkis used. ๐คซ
Added in version 258.
-h,--helpโ print a short help text and exit.--versionโ print a short version string and exit.
๐ EXIT STATUS ๐
on success, 0 is returned. otherwise, a non-zero failure code. that's it, that's the whole vibe check. โญ
๐ EXAMPLE ๐
โจ Example 1. Start-up Notification and Status Updates โจ
Okay bestie, picture this: a lil shell daemon that does its setup, then announces itself to the init system once its communication channel is all ready. Then, the whole time it's running, it keeps dropping status updates like it's posting to its story. ๐
#!/bin/sh
mkfifo /tmp/waldo
systemd-notify --ready --status="Waiting for data..."
while : ; do
read -r a < /tmp/waldo
systemd-notify --status="Processing $a"
# Do something with $a ...
systemd-notify --status="Waiting for data..."
done
No cap, that's the whole vibe: mkfifo sets up the channel, --ready says "we're up, bestie," --status keeps everyone in the loop, and the while : ; do loop just keeps on keeping on forever. ๐โจ
๐ SEE ALSO ๐
The squad, the group chat, the whole friend group you should go hang out with next:
And that's a wrap on SYSTEMD-NOTIFY(1), bestie!! ๐๐ฆ This lil masterpiece is from systemd 262.1, and yeah it's dated โ manuals age like fine wine, not like milk, so you're good. Go forth and notify. ๐๐
๐ฆ 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