我可以成功启动/停止创建 tmux 会话的服务。该服务如下:
test1.service:
[Unit]
Description=First test service
[Service]
Type=forking
User=lancer
ExecStart=/usr/bin/tmux new-session -s test1 -d
ExecStop=/usr/bin/tmux kill-session -t test1
[Install]
WantedBy=multi-user.target
$ sudo systemctl start test1.service
和
$ sudo systemctl stop test1.service
都成功了。现在我想有另一个 tmux 会话,我可以从另一个服务控制它。所以我创建了这个 test2.service:
[Unit]
Description=Second test service
[Service]
Type=forking
User=lancer
ExecStart=/usr/bin/tmux new-session -s test2 -d
ExecStop=/usr/bin/tmux kill-session -t test2
[Install]
WantedBy=multi-user.target
问题: 这两个都可以单独使用。我可以通过以下方式查看相应的 tmux 会话:
$ tmux ls
如果我启动其他服务,则不会发生任何事情。我只有之前的 tmux 会话。有人可以帮忙吗?
答案1
Type=forking
此处的类型不正确。它使 systemd 期望tmux
进程(从 运行ExecStart=
)分叉。但这tmux
并不总是分叉。
如果没有 tmux 服务器,
tmux
命令将分叉。新tmux
进程将成为服务器,在原始tmux
进程退出后它将继续存在。这正是 systemd 对 的期望Type=forking
。这就是为什么两个服务中的任何一个都可以单独运行。如果已经有一个 tmux 服务器,该
tmux
命令将与其通信以创建会话;但它不会分叉,也不需要分叉。进程将退出而不留下分叉的进程,但它仍会报告成功。我的测试表明,在这种情况下ExecStop=
会执行。在你的情况下会ExecStop=
立即终止新创建的会话。你没有注意到会话短暂地存在,你认为什么都没有发生。
解决这个问题的一种方法是创建一个启动 tmux 服务器的“主”服务一定。因为它Type=forking
是正确的。您可以从中启动虚拟会话,或者使用start-server
(使用exit-empty off
)并让它在没有任何会话的情况下运行。
我认为,创建实际会话的服务应该使用Type=oneshot
。它们应该想要 ( ) 或需要 ( )“主”服务。我对 systemd 不够熟悉,无法提出详细的解决方案;我甚至不确定使用“主”服务的想法是否最好。RemainAfterExit=yes
Wants=
Requires=
无论如何,现在你知道为什么在某些情况下据称什么也没有发生。
答案2
感谢@Kamil Maciorowski,我找到了解决方案。三个步骤:
- 定义一个主服务,主服务,如下所示:
[Unit]
Description=tmux master service
[Service]
Type=forking
User=lancer
ExecStart=/usr/bin/tmux new-session -s master -d
ExecStop=/usr/bin/tmux kill-session -t master
[Install]
WantedBy=multi-user.target
- 定义第一个服务, 测试1.服务,如下所示:
[Unit]
Description=tmux test 1 service
PartOf=master.service
After=master.service
[Service]
Type=oneshot
RemainAfterExit=yes
User=lancer
ExecStart=/usr/bin/tmux new-session -s test1 -d
ExecStop=/usr/bin/tmux kill-session -t test1
[Install]
WantedBy=multi-user.target
- 定义第二项服务, 测试2.服务,如下所示:
[Unit]
Description=tmux test 2 service
PartOf=master.service
After=master.service
[Service]
Type=oneshot
RemainAfterExit=yes
User=lancer
ExecStart=/usr/bin/tmux new-session -s test2 -d
ExecStop=/usr/bin/tmux kill-session -t test2
[Install]
WantedBy=multi-user.target
笔记:
- @Kamil Maciorowski 解释了原因
forking
和oneshot
用途。 - master.service 创建一个名为的虚拟 tmux 会话掌握它不执行任何操作,只是托管其他实际的 tmux 会话。
- 在 test1 和 test2 服务中,
After
是为了确保在启动时,test1 和 test2 服务在 master 服务之后启动。 - 在 test1 和 test2 服务中,
PartOf
要确保如果 master 停止,test1 和 test2 服务也会停止。如果没有这个,如果 master 停止,test1 和 test2 状态显示它们仍然处于活动状态。