我有一个 systemd 服务,它是一个控制台应用程序,这意味着它是通过向其 stdin 发送命令来控制的,并将信息输出到 sdout。我如何设置 systemd 服务,以便我可以连接到它的 stdin 并在任何时候给它命令,然后与它分离,并在必要时重复?
Jos*_*ris 12
我可以想到多种方法来做到这一点。当然,每个人都有自己的警告。
可能最直接的方法是创建一个带有专用 tty 的简单服务,类似于:
# /etc/systemd/system/systemd-interactive-simple-tty.service
[Unit]
Description=Example systemd interactive simple tty service
After=getty.service
[Service]
# https://www.freedesktop.org/software/systemd/man/systemd.exec.html
ExecStart=/usr/local/sbin/systemd-interactive.bash
StandardInput=tty-force
TTYVHangup=yes
TTYPath=/dev/tty20
TTYReset=yes
# https://www.freedesktop.org/software/systemd/man/systemd.service.html
Type=simple
RemainAfterExit=false
Restart=always
RestartSec=5s
[Install]
WantedBy=default.target
Run Code Online (Sandbox Code Playgroud)
以下选项适用于上述简单服务:
conspy对文本模式虚拟控制台进行(远程)控制。这可能是您最好的选择(使用上述 tty 服务)。它可以通过大多数扩展包存储库获得,并且易于使用,如下所示:
conspy 20 # hit ESC+ESC+ESC (3 times quickly, to exit)
Run Code Online (Sandbox Code Playgroud)chvt 的工作方式类似于conspy
但使 /dev/ttyN 成为前台(本地)终端。它是kbd集合的一部分,默认安装在几乎所有现代 Linux 发行版上。这就是为什么我认为值得一提的原因。主要的警告chvt
是它要求您使用附带的键盘,这可能不是您想要的。对于上面的服务示例,chvt
可以这样使用:
chvt 20 # ALT+F1 to return to /dev/tty1
Run Code Online (Sandbox Code Playgroud)reptyr使用ptrace(2)
系统调用附加到远程程序(通过它的 PID)。这是一种conspy
与 &完全不同的方法chvt
,但也适用于上述服务定义。
请记住reptyr
,它本身并不真正支持“分离”。它的 termcap 支持也不是很强大。通常,reptyr
与screen和/或tmux结合使用,因为它们提供了一种更无缝的“分离”方式;我发现这reptyr
是一个很棒的利基工具,可以将现有的 PID 移动到screen
会话、tmux
窗口或窗格中。
那说; 我把这个选项放在这里,尽管放在最后,因为它仍然可以在reptyr
没有screen
或 的情况下使用tmux
。主要的警告是,如果您退出该过程(例如 ^C),而不是将其(再次)复制到另一个 tty/pty(通过另一个 shell)。向进程发送中断可能会导致它中止,我相信你知道其余的。
也许这没问题,特别是如果该过程并不重要并且 systemd 服务配置为Restart=always
如上所示。如果进程“中断”,那么 systemd 将自动重新启动它(systemd 的另一个很酷的功能!)。也有不同的值Restart
。天啊。
reptyr
可以通过大多数扩展包存储库获得并且可以使用,如下所示:
reptyr $(systemctl status systemd-interactive-simple-tty.service | grep Main\ PID | awk '{print $3}') # or just reptyr <pid>
Run Code Online (Sandbox Code Playgroud)另一种(更复杂 [意味着有更多可能失败])方法是使用 screen 创建一个分叉服务,类似于:
# /etc/systemd/system/systemd-interactive-forking-screen.service
[Unit]
Description=Example systemd interactive forking screen service
[Service]
# https://www.freedesktop.org/software/systemd/man/systemd.exec.html
ExecStartPre=-/usr/bin/screen -X -S ${SCREEN_TITLE} kill # [optional] prevent multiple screens with the same name
ExecStart=/usr/bin/screen -dmS ${SCREEN_TITLE} -O -l /usr/bin/bash -c /usr/local/sbin/systemd-interactive.bash
# https://www.freedesktop.org/software/systemd/man/systemd.service.html
Type=forking
Environment=SCREEN_TITLE=systemd-interactive
RemainAfterExit=false
Restart=always
RestartSec=5s
SuccessExitStatus=1
[Install]
WantedBy=default.target
Run Code Online (Sandbox Code Playgroud)
screen是一个全屏窗口管理器,它在多个进程之间多路复用一个物理终端。它比第一个简单选项中列出的任何内容都要复杂得多。就我个人而言,我已经使用 screen 很长时间了,并且对大多数事情都感到足够信任它。这是一个非常宝贵的工具。
与上述相比的主要优势是不错的 termcap 支持(虽然不如 tmux 的好)。这只是意味着您的退格键、箭头等将比使用conspy
或更好reptyr
。 screen
可以通过大多数基础包存储库获得,并且可以像这样使用:
screen -r systemd-interactive # CTRL-A+D to detach
Run Code Online (Sandbox Code Playgroud)分叉屏幕的类似方法是 fork tmux
。的 systemd 服务tmux
几乎与screen
. 但是,我不打算详细说明这一点,因为已经很晚了而且我很累。是的,我使用tmux
的比screen
(这些天)多得多。
事实上,我现在正在 Neovim 窗格中编写此内容tmux
。但是,我仍然使用screen
了更长的时间。根据我的经验和观点,tmux
对于这样的事情来说太过分了。当然tmux
是更新的,具有更多的功能,并且是一个比screen
但是更好的外壳多路复用器......它甚至更复杂。伴随着额外的复杂性而来的是一些额外的不稳定性。
更重要的是,至少对我来说,tmux
崩溃比屏幕更频繁。我将 screen 列为 #2 是因为,如果是我,对于类似的东西,我可能只会将 #1 与conspy
.
取决于你的程序;命名管道...... systemd 服务也支持它们!IE
StandardInput=/path/to/named/pipe|
Run Code Online (Sandbox Code Playgroud)... 和更多。
归档时间: |
|
查看次数: |
10308 次 |
最近记录: |