我目前正在将所有 crontab 配置移植到 systemd-services 中,即为需要在我的计算机上自动启动的任务创建单元。
其中一个单元让我头疼。我将其称为“uplink.service”,它的目的是调用一个脚本来构建到我的服务器的反向 ssh 隧道并建立该隧道。这是我创建的单元:
[Unit]
Description = SSH-Uplink
After = network.target
[Service]
ExecStart = /bin/bash /root/script/uplink.sh
[Install]
WantedBy = multi-user.target
这是该单元指向的脚本:
ssh -fNC -R XXXX:localhost:22 user@ip -pXXXX -i ~/script/id_rsa
touch /tmp/uplinkonline
如您所见,为了调试,此脚本尝试在 /tmp 中创建一个名为 uplinkonline 的新文件。这有效;该文件是在启动服务后创建的,因此脚本本身被成功调用。
这是尝试启动 systemctl 后的输出:
uplink.service - SSH-Uplink
Loaded: loaded (/etc/systemd/system/uplink.service; disabled;
vendor preset: disabled)
Active: inactive (dead)
Nov 07 10:44:01 loki systemd[1]: Started SSH-Uplink.
该脚本本身可以在手动启动或通过 crontab 启动时调用它时工作。但不知何故,systemd 似乎期望不同的行为并退出,而不启动 SSH 连接。我哪里做错了?
答案1
您的脚本ssh
在后台启动并且不会保留下来,而 systemd 希望它执行的程序在服务启动时保持运行。
Type=oneshot
您需要做的就是通过在服务单元中配置它来告诉 systemd 这是一项一次性服务。您可能还想包括在内RemainAfterExit=yes
,以便 systemd 不断将服务列为“up”。
简而言之,将您的服务文件更新为以下内容:
[Unit]
Description=SSH-Uplink
After=network.target
[Service]
Type=oneshot
ExecStart=/bin/bash /root/script/uplink.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
(请注意,systemd 单元文件的常用样式在“=”周围没有空格,所以我也修复了这个问题。)
您可能需要考虑添加一个ExecStop=
命令来拆除 SSH 隧道,以便systemctl stop uplink
按预期工作。