![通过向 screen 会话发送命令来停止 systemd 服务](https://linux22.com/image/127397/%E9%80%9A%E8%BF%87%E5%90%91%20screen%20%E4%BC%9A%E8%AF%9D%E5%8F%91%E9%80%81%E5%91%BD%E4%BB%A4%E6%9D%A5%E5%81%9C%E6%AD%A2%20systemd%20%E6%9C%8D%E5%8A%A1.png)
我跑比格利布特使用以下命令作为屏幕会话中的守护进程
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