作为 systemd 服务运行两个 tmux 会话

作为 systemd 服务运行两个 tmux 会话

我可以成功启动/停止创建 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=yesWants=Requires=

无论如何,现在你知道为什么在某些情况下据称什么也没有发生。

答案2

感谢@Kamil Maciorowski,我找到了解决方案。三个步骤:

  1. 定义一个主服务,主服务,如下所示:
[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. 定义第一个服务, 测试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
  1. 定义第二项服务, 测试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

笔记

  1. @Kamil Maciorowski 解释了原因forkingoneshot用途。
  2. master.service 创建一个名为的虚拟 tmux 会话掌握它不执行任何操作,只是托管其他实际的 tmux 会话。
  3. 在 test1 和 test2 服务中,After是为了确保在启动时,test1 和 test2 服务在 master 服务之后启动。
  4. 在 test1 和 test2 服务中,PartOf要确保如果 master 停止,test1 和 test2 服务也会停止。如果没有这个,如果 master 停止,test1 和 test2 状态显示它们仍然处于活动状态。

相关内容