Ctrl+c または Ctrl+z SSH 経由で送信するには?

Ctrl+c または Ctrl+z SSH 経由で送信するには?

PuTTYまたはOpenSSHで+を押すと、CtrlSSHホストに正確に何が送信されるのかを判断します。c私が望むのは、Ctrlユーザーが+を押したときと同じ制御コードをプログラムで送信することですz。これまでに送信するたびに、または^C単に印刷されます。端末にエスケープされたことを知らせる一種の追加情報が必要ですか?\cc\003^C

SSHホストに接続されているSSHセッションにプログラムで文字を送信しています。 OpenSSHクライアントを開き、キーボードで+を押したCtrlときと同じ効果を見たいです。c

答え1

もし Ctrl+ cSSHを介して送信され、バイトです(^C例:16進数、0x038進数003、ASCII ETX)。
もし Ctrl+ zSSHを介して送信され、バイトです(^Z例:16進数、0x1a8進数032、ASCII SUB)。

Ctrlクライアントの+がcサーバーに到達するバイトを生成したり、生成しない可能性があるため、「if」を書きました。サーバー側では、このバイトはSSHサーバーによって開始されたプログラムに到達してもしなくてもかまいません。

WindowsのPuTTYがこの問題をどのように処理するのか正確にはわかりませんが、Linux(Linuxクライアント+ Linuxサーバーなど)のメカニズムはわかっています。私の答えは他のいくつかの答えの情報を要約します。

sshターミナルエミュレータとして実行しているとし、Ctrl+を押しますc。何が起こるのか?

  1. 端末エミュレータの生成^C

  2. そのバイトを傍受して信号に「変換」することもそうでないかもしれないttyラインルールがあります。

    • SIGINT をトリガするようにラインルールが設定されている場合は、^C現在のフォアグラウンドプロセスグループに SIGINT を送信します。sshフォアグラウンドプロセスグループに存在する場合は、シグナルを受信して​​終了します。

    • ラインルールが^C特別な処理を行わないように設定されている場合は、^C「通常」バイト(aまたは5)などのように転送され、ssh読み込まれてリモートエンドに転送されます。それから…

  3. リモート側に tty を割り当てることも、そうでない場合もあります。

    • tty がない場合、SSH サーバーで開始されたプログラムは^C標準入力を受け取ります。

    • ttyが存在する場合、^C特別な処理のために構成または構成されない可能性がある回線規則が存在します。ローカルで発生するのと同様に、リモート回線ルールはSIGINTを(リモート)フォアグラウンドプロセスグループに送信するか、^C「通常」バイトのように渡します。

sshリモート側にttyを割り当てたり割り当てたりせずに起動し、ローカル端末が特別な処理を停止しないようにしますssh … some_command。実際、local +はローカルプログラム(つまりそれ自体)を終了します。ただし、ローカル接続ルールをバイパスするようにパイプする場合、リモート側から任意のデータ(バイトを含む)をパイプでき、データを破損する可能性がある接続ルールはありません。ssh -T …^CCtrlcsshssh^Csome_command

sshコマンドが不要またはコマンドで始まった-t-tt場合によっては必須)リモート側にttyを割り当て、ローカル端末に^C特別な処理を停止させます。実際、local Ctrl+はcローカルプログラム(つまりそれ自体)を終了しませんが、リモート回線ルールがそれを処理するリモート側に移動するため、sshlocal +はリモートプログラムを終了できます。リモート回線ルールは、それがローカル+から来ているのか(たとえば)パイプから来るのかを知ることはできません。 ttyがリモート側に割り当てられると、パイプを介して任意のデータを確実に送受信できません。リモート側の接続ルールによりデータが破損します。私の質問からいくつかの追加の洞察を得ることができます。^CCtrlc^CCtrlcprintf "\003"sshsshssh独立したstdin、stdout、stderr、ttyがあります。

これまでに送信するたびに、または^C単に印刷されます。\cc\003

可能性:

  • リモート側にはttyがないため、^CSIGINTに「変換」する行規則はなく、プログラムは実際に見える形式(たとえば)に「印刷します」cat -A

  • あるいは、リモートエンドにttyがありますが、行ルールは^C特別な処理を行わないように構成されています。ターミナルドライバXORは「印刷」します(入力で得られる内容を(カラットで)エコーするようにターミナルドライバを設定するのは簡単ですstty ctlecho。)

  • あるいは、リモートエンドにttyがあり、ライン規律は^C特別な処理のために設定されていますが、プログラムはSIGINTをキャッチして自己終了するのではなく「印刷」します。

答え2

このような:

(echo ping google.com; sleep 3; printf "\003"; ) |
  ssh -tt localhost

答え3

パテでCTRL-Cを押すかSSHを開くと、SSHホストに正確に何が送信されているかを把握しようとしています。

わかりません。

私が望むのは、ユーザーがCTRL-Zを押したときに発生したのと同じ制御コードを実用的に送信することです。

プログラムでCtrl + Cを送信するには、SIGINTをsshに送信します。たとえば、次のようになります。

killalll -s SIGINT ssh

ctrl+CアクセスできるすべてのSSHセッションを押すのと同じです。また、Ctrl + Zの場合はSIGTSTPを使用します。

killall -s SIGTSTP ssh

すべてのssh端末でCtrl + Z ...を押して特定のsshセッションに送信し、そのssh PIDを取得してkillを使用します。

kill -s SIGTSTP PID

Ctrl + Zは、このPIDに属するSSHセッションに送信されます。

関連情報