Systemd
使 systemd 服務了解配置文件中的更改
我的
systemd
服務或多或少是這樣的:[Service] ExecStart=/usr/local/bin/binary subcommand User=my-user Group=my-group EnvironmentFile=/etc/my-service/config
我正在更改內容
/etc/my-service/config
我應該執行
daemon-reload
還是重新載入服務?請注意,我的單元文件沒有
ExecReload
指令;這會影響systemctl reload my-service
的行為嗎?
既
daemon-reload
不會也reload
不會EnvironmentFile=
被您的主程序讀取。手冊頁說列出的文件
EnvironmentFile=
將在執行該過程之前不久被讀取。
- 這表明
start
或restart
將導致文件被讀取。那是因為start
或restart
將執行該過程。- 這也暗示
daemon-reload
不會因為daemon-reload
沒有start
或restart
單位而產生影響。- 這也表明
reload
不會產生任何影響,因為reload
不創建主程序。它只提供了向主程序發送信號以重新載入其配置的機會。如果您沒有ExecReload=
定義,則尤其如此。輔助實驗
$ systemctl --user cat env.service # /home/stew/.config/systemd/user/env.service [Service] ExecStart=/bin/bash -c "while true; do sleep 1; echo $EXAMPLE_ENV; done" EnvironmentFile=%h/env $ cat ~/env EXAMPLE_ENV="Hi" $ systemctl --user start env.service
然後我在操作期間監控日誌:
$ journalctl --user -u env.service -f ... Feb 11 15:35:47 stewbian systemd[1108]: Started env.service. Feb 11 15:35:48 stewbian bash[911848]: Hi Feb 11 15:35:49 stewbian bash[911848]: Hi
然後我更改了環境文件,看到輸出沒有變化
$ sed -i -e 's/Hi/Yo/' ~/env ... Feb 11 15:37:13 stewbian bash[911848]: Hi Feb 11 15:37:14 stewbian bash[911848]: Hi Feb 11 15:37:15 stewbian bash[911848]: Hi
然後我嘗試 a
systemctl reload
並看到輸出沒有變化:$ systemctl --user reload env.service Failed to reload env.service: Job type reload is not applicable for unit env.service. ... Feb 11 15:38:14 stewbian bash[911848]: Hi Feb 11 15:38:15 stewbian bash[911848]: Hi
然後我嘗試 a
daemon-reload
並看到輸出沒有變化:$ systemctl --user daemon-reload ... Feb 11 15:38:46 stewbian bash[911848]: Hi Feb 11 15:38:47 stewbian bash[911848]: Hi
所以然後我嘗試重新啟動並查看更改。
$ systemctl --user restart env.service ... Feb 11 15:39:29 stewbian bash[911848]: Hi Feb 11 15:39:30 stewbian bash[911848]: Hi Feb 11 15:39:30 stewbian systemd[1108]: Stopping env.service... Feb 11 15:39:30 stewbian systemd[1108]: Stopped env.service. Feb 11 15:39:30 stewbian systemd[1108]: Started env.service. Feb 11 15:39:31 stewbian bash[912531]: Yo Feb 11 15:39:32 stewbian bash[912531]: Yo
一件有趣的事情是添加
ExecReload=/bin/bash -c 'echo $EXAMPLE_ENV
到單元中。在那種情況下,我得到這個:Feb 11 15:58:24 stewbian bash[914611]: Hi Feb 11 15:58:25 stewbian bash[914611]: Hi Feb 11 15:58:26 stewbian systemd[1108]: Reloading env.service... Feb 11 15:58:26 stewbian bash[914640]: Yo Feb 11 15:58:26 stewbian systemd[1108]: Reloaded env.service. Feb 11 15:58:26 stewbian bash[914611]: Hi Feb 11 15:58:27 stewbian bash[914611]: Hi
所以在這裡你可以看到在啟動之前
systemd
確實讀過,但只會將新環境傳遞給新程序。它不會改變現有流程的環境。EnvironmentFile=``ExecReload=
我通過將這些
bash
東西放在一個單獨的腳本中來重試這個,以確保 systemd 環境變數替換在解析行期間不會影響任何東西Exec*=
……結果相同。支持文件
man systemd.exec
:EnvironmentFile= ... The files listed with this directive will be read shortly before the process is executed (more specifically, after all processes from a previous unit state terminated. This means you can generate these files in one unit state, and read it with this option in the next. The files are read from the file system of the service manager, before any file system changes like bind mounts take place).
man systemctl
:reload PATTERN... Asks all units listed on the command line to reload their configuration. Note that this will reload the service-specific configuration, not the unit configuration file of systemd. If you want systemd to reload the configuration file of a unit, use the daemon-reload command. In other words: for the example case of Apache, this will reload Apache's httpd.conf in the web server, not the apache.service systemd unit file. This command should not be confused with the daemon-reload command. daemon-reload Reload the systemd manager configuration. This will rerun all generators (see systemd.generator(7)), reload all unit files, and recreate the entire dependency tree. While the daemon is being reloaded, all sockets systemd listens on behalf of user configuration will stay accessible. This command should not be confused with the reload command. In other words: for the example case of Apache, this will reload Apache's httpd.conf in the web server, not the apache.service systemd unit file. This command should not be confused with the daemon-reload command.
man systemd.service
:ExecReload= Commands to execute to trigger a configuration reload in the service. This argument takes multiple command lines, following the same scheme as described for ExecStart= above. Use of this setting is optional. Specifier and environment variable substitution is supported here following the same scheme as for ExecStart=. One additional, special environment variable is set: if known, $MAINPID is set to the main process of the daemon, and may be used for command lines like the following: ExecReload=kill -HUP $MAINPID Note however that reloading a daemon by sending a signal (as with the example line above) is usually not a good choice, because this is an asynchronous operation and hence not suitable to order reloads of multiple services against each other. It is strongly recommended to set ExecReload= to a command that not only triggers a configuration reload of the daemon, but also synchronously waits for it to complete. For example, dbus- broker(1) uses the following: ExecReload=busctl call org.freedesktop.DBus \ /org/freedesktop/DBus org.freedesktop.DBus \ ReloadConfig