Systemd

服務啟動後 systemd 連接到 stdin/stdout

  • October 8, 2019

我有一個 systemd 服務,它是一個控制台應用程序,這意味著它是通過向其標準輸入發送命令來控制的,並將資訊輸出到 sdout。如何設置 systemd 服務,以便我可以連接到它的標準輸入並在任何時候給它命令,然後脫離它,並在必要時重複?

我可以想出多種方法來做到這一點。當然,每個都有自己的警告。

  1. 可能最直接的方法是創建一個帶有專用 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

以下選項將適用於上述簡單服務:

  1. conspy對文本模式虛擬控制台進行(遠端)控制。這可能是您最好的選擇(使用上述 tty 服務)。它可通過大多數擴展包儲存庫獲得,並且易於使用,如下所示:
 conspy 20 # hit ESC+ESC+ESC (3 times quickly, to exit)
 [chvt 的](http://man7.org/linux/man-pages/man1/chvt.1.html)工作方式與 /dev/ttyN 類似,`conspy`但它使 /dev/ttyN 成為前台(本地)終端。它是[kbd](http://ftp.altlinux.org/pub/people/legion/kbd)集合的一部分,並且預設安裝在幾乎所有現代 Linux 發行版上。這就是為什麼我認為它值得一提。主要的警告`chvt`是它需要您使用附帶的鍵盤,這可能不是您想要的。對於上面的服務範例,`chvt`可以這樣使用:
vt 20 # ALT+F1 to return to /dev/tty1
 [reptyr](https://github.com/nelhage/reptyr)使用`ptrace(2)`系統呼叫附加到遠端程序(通過它的 PID)。這是與`conspy`&完全不同的方法`chvt`,但也適用於上述服務定義。


記住`reptyr`,它本身並不真正支持“分離”。它的 termcap 支持也不是很強大。通常,`reptyr`與[screen](https://www.gnu.org/software/screen/)和/或[tmux](https://github.com/tmux/tmux)一起使用,因為它們提供了一種更無縫的“分離”方式;我發現`reptyr`這是一個很棒的利基工具,可以將現有的 PID 移動到`screen`會話或`tmux`視窗或窗格中。


就是說;我把這個選項放在這裡,儘管放在最後,因為它仍然可以在`reptyr`沒有`screen`or的情況下使用`tmux`。主要的警告是,如果你打破了程序(例如 ^C),而不是(再次)將它重新復製到另一個 tty/pty(通過另一個 shell)。向程序發送中斷可能會導致它中止,我相信你知道其餘的。


許沒關係,特別是如果程序不是關鍵的並且 systemd 服務配置為`Restart=always`如上所示。如果程序“中斷”,則 systemd 將自動重新啟動它(systemd 的另一個很酷的功能!)。也有不同的值`Restart`。YMMV。


eptyr`可通過大多數擴展包儲存庫獲得併且可以使用,如下所示:
ptyr $(systemctl status systemd-interactive-simple-tty.service | grep Main\ PID | awk '{print $3}') # or just reptyr <pid>
2. 另一個(更複雜的

$$ meaning there's more that could fail $$) 方法是使用螢幕創建分叉服務,類似於:

/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


[screen](https://www.gnu.org/software/screen/)是一個全屏視窗管理器,它在多個程序之間多路復用一個物理終端。它比第一個簡單選項中列出的任何內容都要復雜得多。就個人而言,我已經使用螢幕很長時間了,並且感覺很舒服,可以在大多數事情上信任它。這是一個非常寶貴的工具。 


與上述相比的主要優勢是不錯的 termcap 支持(儘管不如 tmux 好)。這只是意味著您的退格鍵、箭頭等將比使用`conspy`or更好`reptyr`。 `screen`可以通過大多數*基本*包儲存庫獲得,並且可以像這樣使用:

screen -r systemd-interactive # CTRL-A+D to detach

3. 與分叉 screen 類似的方法是 fork `tmux`。的 systemd 服務`tmux`幾乎與`screen`. 但是,我不會詳細說明這一點,因為,已經很晚了,我很累。是的,我用`tmux` *的*比`screen`(這些天)多得多。 


事實上,我現在正在neovim 窗格中寫這個`tmux`。但是,我仍然使用`screen`了更長的時間。以我的經驗和意見,`tmux`對於這樣的事情來說是矯枉過正的。肯定`tmux`是更新的,有更多的功能,並且是一個比`screen`但是更好的外殼多路復用器......它甚至更複雜。伴隨著額外的複雜性而來的是一些額外的不穩定性。 


至少對我來說,更重要的是`tmux`崩潰比螢幕更頻繁。我將 screen 列為#2,因為如果是我,對於類似的事情,我可能只是將#1 與`conspy`.
4. 取決於您的程序;命名管道... systemd 服務也支持它們!IE

StandardInput=/path/to/named/pipe|



... 和更多。

引用自:https://unix.stackexchange.com/questions/453998