コンソールアプリケーションであるsystemdサービスがあります。つまり、コマンドをそのstdinに送信することによって制御され、情報をsdoutに出力します。どのようにすれば、systemdサービスをセットアップして、そのstdinに接続し、任意の時点でそれにコマンドを与え、これから切り離して、必要に応じて繰り返すことができますか?
これを行う方法はいくつか考えられます。もちろん、それぞれに独自の警告があります。
おそらく最も簡単な方法は、次のような専用の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 はconspy
と同様に機能しますが、/ dev/ttyNをフォアグラウンド(ローカル)端末にします。これは kbd コレクションの一部であり、ほぼすべての最新のLinuxディストリビューションにデフォルトでインストールされます。それが私が言及する価値があると思った理由です。 chvt
の主な注意点は、接続されているキーボードを使用する必要があることです。上記のサービスの例では、chvt
は次のように使用できます。
_ chvt 20 # ALT+F1 to return to /dev/tty1
_
reptyr は、ptrace(2)
システムコールを使用して、リモートプログラムに(PIDを介して)接続します。これはconspy
&chvt
とはまったく異なるアプローチですが、上記のサービス定義でも機能します。
reptyr
自体は、実際には「切り離し」をサポートしていないことに注意してください。 termcapのサポートもあまり堅牢ではありません。通常、reptyr
は screen や tmux と組み合わせて使用されます。これは、よりシームレスに「切り離す」方法を提供するためです。 reptyr
は、既存のPIDをscreen
セッションまたはtmux
ウィンドウまたはペインに移動するための優れたニッチツールです。
それは言った; reptyr
またはscreen
なしでtmux
を使用することはまだ可能であるため、このオプションを最後に配置しました。主な注意点は、(別のシェルを介して)別のtty/ptyに(再度)反復するのではなく、プロセス(例えば^ C)を中断する場合です。プロセスにブレークを送信すると、プロセスが中止される可能性があります。残りを知っていると思います。
特にプロセスが重要ではなく、上で示したようにsystemdサービスが_Restart=always
_に設定されている場合は特に問題ないでしょう。プロセスが「壊れた」場合、systemdは自動的に再起動します(systemdのもう1つの優れた機能です)。 Restart
にも異なる値があります。 YMMV。
reptyr
は、ほとんどの拡張パッケージリポジトリから入手でき、次のように使用できます。
_ reptyr $(systemctl status systemd-interactive-simple-tty.service | grep Main\ PID | awk '{print $3}') # or just reptyr <pid>
_
別の(より複雑な[失敗する可能性があることを意味する])アプローチは、次のように画面を使用してフォークサービスを作成することです。
_# /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 は、複数のプロセス間で物理端末を多重化するフルスクリーンウィンドウマネージャーです。これは、最初の単純なオプションにリストされているものよりもかなり複雑です。個人的に、私は画面を長い間使用しており、ほとんどのもので信頼できるほど快適に感じています。それは非常に貴重なツールです。
上記に対する主な利点は、適切なtermcapサポートです(ただし、tmuxの場合ほどではありません)。これは、バックスペースキー、矢印などがconspy
またはreptyr
よりもうまく機能することを意味します。 screen
は、ほとんどのbaseパッケージリポジトリから利用でき、次のように使用できます。
_screen -r systemd-interactive # CTRL-A+D to detach
_
画面をフォークする同様の方法は、tmux
をフォークすることです。 tmux
のsystemdサービスは、screen
のsystemdサービスとほとんど同じです。しかし、これは詳しく説明するつもりはありません。まあ、それは遅く、私は疲れているからです。はい、私はtmux
をscreen
(最近)より多く使用します。
実際、私はこれを現在tmux
のneovimペインで書いています。しかし、私はscreen
をまだずっと長く使用しています。私の経験と意見では、tmux
はこのようなものには過剰です。確かにtmux
はscreen
よりも新しく、より多くの機能を備えており、はるかに優れたシェルマルチプレクサですが...より複雑です。その余分な複雑さに加えて、いくつかの追加の不安定さが伴います。
少なくとも私にとってより重要なのは、tmux
が画面よりも頻繁にクラッシュすることです。 screenを#2と表示したのは、それが私である場合、そのような場合には、おそらくconspy
で#1を使用するだけだからです。
プログラムによって異なります。名前付きパイプ... systemdサービスもそれらをサポートします!つまり.
_StandardInput=/path/to/named/pipe|
_
... もっと。