我编写了一个 systemd 文件,使用特定配置文件启动我的 VPN 服务。我希望每次服务启动时都用随机选择的配置文件替换此文件。
到目前为止我已经尝试过使用
ExecStartPre=cp -f `ls /etc/openvpn/ovpn_udp/au* | shuf -n 1` /etc/openvpn/%i.conf
将随机挑选的文件复制到指定的配置文件。我尝试过的一些替代方法是
- 使用 rsync -c 代替 cp
- 整个 ExecStartPre 命令用双引号引起来
- 逃避“
最后,我还尝试了以下 ExecStart
ExecStart=/usr/sbin/openvpn --config `ls /etc/openvpn/ovpn_udp/au* | shuf -n 1`
一切都毫无效果。
目前systemd文件如下
[Unit]
Description=OpenVPN Robust And Highly Flexible Tunneling Application On %I
After=network.target
[Service]
Type=notify
PrivateTmp=true
ExecStartPre=cp -f `ls /etc/openvpn/ovpn_udp/au* | shuf -n 1` /etc/openvpn/%i.conf
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/%i.conf
[Install]
WantedBy=multi-user.target
我希望在每次启动服务之前更改配置文件,但到目前为止我没有看到任何错误或配置文件被替换。
任何帮助都将不胜感激。
谢谢
答案1
ExecStart= 命令不是由 shell 运行的并且不提供通常的 shell 语言功能。它唯一拥有的功能是引用和 $variable 替换 – 但是它不具有管道符或“反引号”或$(命令替换)。
为了使用这些功能,a)明确运行类似/bin/sh的shell:
ExecStart=/bin/sh -c "cp `foo | bar` baz"
或者 b) 将命令移到 shell 脚本中并运行那来自 ExecStart=。
请注意,OpenVPN 本身已经支持声明多个服务器在同一配置中,使用<connection>
块和--remote-random
,如其手册页所示:
client
remote-random
<connection>
remote foo.example.com 1194 udp
</connection>
<connection>
remote bar.example.com 1194 udp
</connection>
答案2
感谢 @grawity,这让事情变得清晰多了。利用您的回答,我现在已经成功将我的 systemd 服务文件修改为以下内容,它完全满足了我的需求。
[Unit]
Description=OpenVPN Robust And Highly Flexible Tunneling Application On %I
After=network.target
[Service]
Type=notify
PrivateTmp=true
ExecStartPre=/bin/bash -c "ls /etc/openvpn/ovpn_udp/au* | shuf -n 1 | xargs -r -n1 -I'{}' cp -f '{}' /etc/openvpn/%i.conf"
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/%i.conf
[Install]
WantedBy=multi-user.target