【问题标题】:Systemctl(?) killing detached screensSystemctl(?) 杀死分离的屏幕
【发布时间】:2024-01-23 13:18:01
【问题描述】:

我有一个用 Go 编写的程序,它以编程方式创建和管理屏幕。这是一个例子:

_, err := exec.Command("screen", "-S", "screen-"+strings.ToLower(name), "-X", "stuff", command+"\n").Output()

这很好用。当我 Control+C 程序时,创建的屏幕保持打开状态(我想要什么!)。但是,我已将其转换为 Ubuntu 上的后台服务。当我运行systemctl stop <service> 时,它会在没有警告的情况下杀死这些屏幕。附加到屏幕也不会阻止这一点(立即转到[screen terminated])。但是,它不会杀死外部创建的屏幕。

这是我的.service

[Unit]
Description=>servicename> background service
After=network-online.target

[Service]
ExecStart=/usr/lib/<servicename>/service

[Install]
WantedBy=multi-user.target

我的rules

%:
    dh $@ --with systemd --parallel

override_dh_auto_install:
    dh_auto_install
    dh_systemd_enable || true
    dh_systemd_start || true

我的control

Package: <name>
Version: 0.2
Architecture: amd64
Priority: optional
Maintainer: <me>
Description: <description>
Depends: screen, iptables
Build-Depends: dh-systemd (>=1.5)

我无法想象是什么导致这些屏幕死机。我很确定它们没有附加到程序中,因为它作为可执行文件运行良好。系统日志没有提到“服务停止”和“服务启动”之外的任何内容。我尝试过在 root 下制作屏幕、不同的用户、运行空屏幕与运行程序等。没有什么值得注意的。

有什么想法吗?

【问题讨论】:

    标签: linux go service systemd gnu-screen


    【解决方案1】:

    systemd 默认情况下会在创建它们的主服务(您的 Go 程序)退出时杀死所有进程(屏幕)。请注意,这不仅是子进程,而且是同一 cgroup 中的任何进程。这是为了确保在服务崩溃时没有剩余进程。

    可以使用.service 单元文件中描述的here 中的键KillMode= 来控制此行为。尽管不建议您将其设置为processnone(以使您的屏幕不受管理并通过systemd 逃避您的服务生命周期管理)。

    【讨论】: