我在~/.config/systemd/user/example.service有一个用户服务,如下所示:
[Unit] Description=Example service After=network.target [Service] ExecStart=/bin/bash -c 'host google.com > /var/tmp/example' [Install] WantedBy=default.target
当然,我试图控制的实际服务确实有用,并访问了networking。 这只是一个简单的例子。
该服务通过systemctl --user enable example.service来systemctl --user enable example.service ,它创build了指向~/.config/systemd/user/example.service的symlink〜 ~/.config/systemd/user/default.target.wants/example.service ~/.config/systemd/user/example.service 。
通过这个设置,以及Arch维基上描述的systemd用户会话,服务以启动时的用户身份启动。 但是,networkingbuild立后并没有真正启动, 相反,它似乎立即开始,因为/var/tmp/example包含:
;; connection timed out; no servers could be reached
(而且,我试图控制的实际服务也无法到达networking,并且出现类似的名称查找错误)
这意味着该服务实际上不会在network.target之后运行。 如何在运行前等待network.target ?
忘掉network.target 。 man systemd.special说:
network.target systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the $network facility.
所以,这个目标主要是针对SysV init脚本的兼容性攻击。
假设您的networking连接由NetworkManager处理,您当然可以依赖此目标,因为NetworkManager.service定义了Before=network.target 。 但这只意味着NetworkManager已经启动,而不是networking连接实际build立。 这可能需要一段时间(DHCP往返,无线握手等),完全是NetworkManager的业务。 至less在我的系统(F18)上有一个叫做NetworkManager-wait-online 。 它使用nm-online应用程序阻塞,直到build立活动连接。 在单元定义Require, Before尝试Require, Before或者单独使用该工具。
我遇到了同样的问题,需要访问互联网的用户级备份脚本。 我通过添加~/.config/systemd/user/wait-for-network.service来解决它,只需ping到google.com直到它可以访问:
[Unit] Description=Ping a server on the internet until it becomes reachable [Service] Type=oneshot ExecStart=/bin/bash -c 'while ! ping -c1 google.com; do sleep 1; done' TimeoutStartSec=60s
然后,我使得我的备份脚本依赖于它:
[Unit] Description=... Requires=wait-for-network.service After=wait-for-network.service
无论您是使用NetworkManager还是其他一些方式来build立连接,这都是有效的。