通过向 screen 会话发送命令来停止 systemd 服务

通过向 screen 会话发送命令来停止 systemd 服务

我跑比格利布特使用以下命令作为屏幕会话中的守护进程

screen -c /home/pi/.screenconf -L -dmS Biglybt_screen /usr/bin/java -cp "/usr/share/java/jna.jar:/home/pi/biglybt_stock/BiglyBT.jar:/home/pi/biglybt_stock/dorkbox-systemtray.jar:/home/pi/biglybt_stock/commons-cli.jar:/home/pi/biglybt_stock/log4j.jar:/home/pi/biglybt_stock/junit.jar:/home/pi/biglybt_stock/swt.jar" -Djava.library.path=/home/pi/biglybt_stock -Dbiglybt.install.path=/home/pi/biglybt_stock -Dazureus.script=/home/pi/biglybt_stock/biglybt -Djava.net.preferIPv4Stack=true -Ddebug.swtexec=1 -Dazureus.config.path=~/.biglybt_stock  com.biglybt.ui.Main --ui=console

我可以通过quit向屏幕会话发送命令来停止守护进程,如下所示

screen -S Biglybt_screen -p 0 -X stuff "quit ^M"

现在我想创建一个服务文件,以便当系统关闭时屏幕会话得到一个quit优雅退出的命令

我尝试过这个服务文件

[Unit]
Description=BiglyBt daemon
After=network-online.target

[Service]
Type=oneshot
User=pi
RemainAfterExit=yes
ExecStart=/usr/bin/screen -c /home/pi/.screenconf -L -dmS Biglybt_screen /usr/bin/java -cp "/usr/share/java/jna.jar:/home/pi/biglybt_stock/BiglyBT.jar:/home/pi/biglybt_stock/dorkbox-systemtray.jar:/home/pi/biglybt_stock/commons-cli.jar:/home/pi/biglybt_stock/log4j.jar:/home/pi/biglybt_stock/junit.jar:/home/pi/biglybt_stock/swt.jar" -Djava.library.path=/home/pi/biglybt_stock -Dbiglybt.install.path=/home/pi/biglybt_stock -Dazureus.script=/home/pi/biglybt_stock/biglybt -Djava.net.preferIPv4Stack=true -Ddebug.swtexec=1 -Dazureus.config.path=~/.biglybt_stock  com.biglybt.ui.Main --ui=console
ExecStop=/usr/bin/screen -S Biglybt_screen -p 0 -X stuff "quit ^M"

[Install]
WantedBy=multi-user.target

但是当我停止服务时,进程只是被终止而不是结束屏幕会话,那么我错过了什么?

更新: 该服务文件有效

[Unit]
Description=BiglyBt daemon
After=network-online.target

[Service]
Environment=DISPLAY=0.0
Type=simple
User=pi
Group=pi
ExecStart=/usr/bin/java -cp "/home/pi/biglybt_stock/BiglyBT.jar:/home/pi/biglybt_stock/swt.jar" -Djava.library.path=/home/pi/biglybt_stock -Dbiglybt.install.path=/home/pi/biglybt_stock -Dazureus.script=/home/pi/biglybt_stock/biglybt -Dazureus.config.path=/home/pi/.biglybt_stock -Dazureus.overridelog=1 -Dazureus.overridelogdir=/home/pi/biglybtlogs/ -Ddebug.swtexec=1 com.biglybt.ui.Main --ui="console,telnet"
ExecStop=/usr/bin/java -cp /home/pi/biglybt_stock/BiglyBT.jar -Djava.library.path=/home/pi/biglybt_stock -Dbiglybt.install.path=/home/pi/biglybt_stock -Dazureus.script=/home/pi/biglybt_stock/biglybt -Dazureus.config.path=/home/pi/.biglybt_stock  com.biglybt.ui.Main --shutdown
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target

现在的问题是我无法再启动biglybt的swt ui(gui)。 swt ui 可以通过远程登录到服务器并发出ui swt 或运行来启动

/usr/bin/java -cp "/home/pi/biglybt_stock/BiglyBT.jar:/home/pi/biglybt_stock/swt.jar" -Djava.library.path=/home/pi/biglybt_stock -Dbiglybt.install.path=/home/pi/biglybt_stock -Dazureus.script=/home/pi/biglybt_stock/biglybt -Dazureus.config.path=/home/pi/.biglybt_stock  -Dazureus.overridelog=1 -Dazureus.overridelogdir=/home/pi/biglybtlogs/ -Ddebug.swtexec=1 com.biglybt.ui.Main --ui="swt" --open

这将向主进程发送请求以启动 swt ui。不幸的是,这在常规终端窗口中运行良好,但是当在 systemd 中运行主进程时,这给出了

Unable to init server: Could not connect: Connection refused

在日志日志里面

答案1

您可能不想screen在其中使用守护进程,systemd因为systemd假设了有关进程如何工作的某些事情,特别是在oneshot模式下。来自systemd.service(5)文档:

的行为oneshot类似于simple;然而,预计该进程必须在 systemd 启动后续单元之前退出。 RemainAfterExit=对于此类服务特别有用。如果既没有指定Type=也没有ExecStart=指定,则这是隐含的默认值。

您的进程不会立即退出,因此oneshot这不是要寻找的正确行为。

看着bigly --help

usage: [options] [torrent [torrent ...]]
 -h,--help        Show this help.
 -u,--ui <uis>    Run <uis>. ',' separated list of user interfaces to run
                  (swt, console, telnet). The first one given will respond
                  to requests without determinable source UI (e.g. further
                  torrents added via command line).
    --closedown   shutdown an existing instance of BiglyBT
    --shutdown    shutdown an existing instance of BiglyBT
    --open        show the BiglyBT interface
    --share       share a resource

Bigly 能够以 telnet 模式启动,这应该足以作为自己的守护进程运行,而无需任何额外的帮助;然后,它可以与正在运行的实例通信,以使用 发送关闭命令--shutdown。考虑到这一点,我们可以在simple模式下运行服务(我排除了不需要运行的类路径引用和命令行选项,因此如果需要,请将它们添加回来):

大服务:

[Unit]
Description=BiglyBt daemon
After=network-online.target

[Service]
Type=simple
User=pi
ExecStart=/usr/bin/java -cp /home/pi/biglybt_stock/BiglyBT.jar -Djava.library.path=/home/pi/biglybt_stock -Dbiglybt.install.path=/home/pi/biglybt_stock -Dazureus.script=/home/pi/biglybt_stock/biglybt -Dazureus.config.path=/home/pi/.biglybt_stock  com.biglybt.ui.Main --ui=telnet
#ExecStop=/usr/bin/java -cp /home/pi/biglybt_stock/BiglyBT.jar -Djava.library.path=/home/pi/biglybt_stock -Dbiglybt.install.path=/home/pi/biglybt_stock -Dazureus.script=/home/pi/biglybt_stock/biglybt -Dazureus.config.path=/home/pi/.biglybt_stock  com.biglybt.ui.Main --shutdown
#SuccessExitStatus=143
ExecStop=/bin/sh -c "nc 127.0.0.1 57006 <<< 'quit iamsure'"

[Install]
WantedBy=multi-user.target

该进程以退出代码 143 退出,因此我将其视为服务的成功条件。由于--shutdown在 telnet 模式下似乎不起作用,我使用 netcat 将退出命令发送到 telnet 服务器(端口 57006 似乎是默认端口。)此外,启动时出现了许多错误情况,但我一直在寻找在让程序运行时我忽略了它们。

telnet 接口绑定到所有接口,因此您可能需要设置防火墙规则以阻止外部连接。

答案2

谢谢@埃里克F和 biglybt github 帐户的支持我能够解决这个问题,这个服务文件现在对我有用

[Unit]
Description=BiglyBt daemon
After=network-online.target

[Service]
Environment="DISPLAY=:0.0"
Type=simple
User=pi
Group=pi
ExecStart=/usr/bin/java -cp "/usr/share/java/jna.jar:/home/pi/biglybt/BiglyBT.jar:/home/pi/biglybt/dorkbox-systemtray.jar:/home/pi/biglybt/commons-cli.jar:/home/pi/biglybt/log4j.jar:/home/pi/biglybt/junit.jar:/home/pi/biglybt/swt.jar" -Djava.library.path=/home/pi/biglybt -Dbiglybt.install.path=/home/pi/biglybt -Dazureus.script=/home/pi/biglybt/biglybt -Dazureus.script.version=9 -Dazureus.overridelog=1 -Dazureus.overridelogdir=/home/pi/biglybtlogs/ -Duser.dir=/home/pi/biglybt com.biglybt.ui.Main --ui="console,telnet"
ExecStop=/usr/bin/java -cp "/home/pi/biglybt/BiglyBT.jar" com.biglybt.ui.Main --shutdown
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

我还创建了一个脚本来启动 swt(gui 界面):

#!/bin/bash
/usr/bin/java -cp "/home/pi/biglybt/BiglyBT.jar" com.biglybt.ui.Main --ui=swt --open

相关内容