Systemd
服務啟動後 systemd 連接到 stdin/stdout
我有一個 systemd 服務,它是一個控制台應用程序,這意味著它是通過向其標準輸入發送命令來控制的,並將資訊輸出到 sdout。如何設置 systemd 服務,以便我可以連接到它的標準輸入並在任何時候給它命令,然後脫離它,並在必要時重複?
我可以想出多種方法來做到這一點。當然,每個都有自己的警告。
- 可能最直接的方法是創建一個帶有專用 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
以下選項將適用於上述簡單服務:
- 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|
... 和更多。