PuTTYまたはOpenSSHで+を押すと、CtrlSSHホストに正確に何が送信されるのかを判断します。c私が望むのは、Ctrlユーザーが+を押したときと同じ制御コードをプログラムで送信することですz。これまでに送信するたびに、または^C
単に印刷されます。端末にエスケープされたことを知らせる一種の追加情報が必要ですか?\cc
\003
^C
SSHホストに接続されているSSHセッションにプログラムで文字を送信しています。 OpenSSHクライアントを開き、キーボードで+を押したCtrlときと同じ効果を見たいです。c
答え1
もし Ctrl+ cSSHを介して送信され、バイトです(^C
例:16進数、0x03
8進数003
、ASCII ETX)。
もし Ctrl+ zSSHを介して送信され、バイトです(^Z
例:16進数、0x1a
8進数032
、ASCII SUB)。
Ctrlクライアントの+がcサーバーに到達するバイトを生成したり、生成しない可能性があるため、「if」を書きました。サーバー側では、このバイトはSSHサーバーによって開始されたプログラムに到達してもしなくてもかまいません。
WindowsのPuTTYがこの問題をどのように処理するのか正確にはわかりませんが、Linux(Linuxクライアント+ Linuxサーバーなど)のメカニズムはわかっています。私の答えは他のいくつかの答えの情報を要約します。
- キーボード入力とテキスト出力はどのように機能しますか?
- 各PTY(擬似端末)コンポーネント(ソフトウェア、マスター側、スレーブ側)の役割は何ですか?
- 「生」デバイスドライバと「調理済み」デバイスドライバの違いは何ですか?
- SSHセッションでCtrl-Cを処理する
ssh
ターミナルエミュレータとして実行しているとし、Ctrl+を押しますc。何が起こるのか?
端末エミュレータの生成
^C
。そのバイトを傍受して信号に「変換」することもそうでないかもしれないttyラインルールがあります。
SIGINT をトリガするようにラインルールが設定されている場合は、
^C
現在のフォアグラウンドプロセスグループに SIGINT を送信します。ssh
フォアグラウンドプロセスグループに存在する場合は、シグナルを受信して終了します。ラインルールが
^C
特別な処理を行わないように設定されている場合は、^C
「通常」バイト(a
または5
)などのように転送され、ssh
読み込まれてリモートエンドに転送されます。それから…
リモート側に tty を割り当てることも、そうでない場合もあります。
tty がない場合、SSH サーバーで開始されたプログラムは
^C
標準入力を受け取ります。ttyが存在する場合、
^C
特別な処理のために構成または構成されない可能性がある回線規則が存在します。ローカルで発生するのと同様に、リモート回線ルールはSIGINTを(リモート)フォアグラウンドプロセスグループに送信するか、^C
「通常」バイトのように渡します。
ssh
リモート側にttyを割り当てたり割り当てたりせずに起動し、ローカル端末が特別な処理を停止しないようにしますssh … some_command
。実際、local +はローカルプログラム(つまりそれ自体)を終了します。ただし、ローカル接続ルールをバイパスするようにパイプする場合、リモート側から任意のデータ(バイトを含む)をパイプでき、データを破損する可能性がある接続ルールはありません。ssh -T …
^C
Ctrlcssh
ssh
^C
some_command
ssh
コマンドが不要またはコマンドで始まった-t
(-tt
場合によっては必須)リモート側にttyを割り当て、ローカル端末に^C
特別な処理を停止させます。実際、local Ctrl+はcローカルプログラム(つまりそれ自体)を終了しませんが、リモート回線ルールがそれを処理するリモート側に移動するため、ssh
local +はリモートプログラムを終了できます。リモート回線ルールは、それがローカル+から来ているのか(たとえば)パイプから来るのかを知ることはできません。 ttyがリモート側に割り当てられると、パイプを介して任意のデータを確実に送受信できません。リモート側の接続ルールによりデータが破損します。私の質問からいくつかの追加の洞察を得ることができます。^C
Ctrlc^C
Ctrlcprintf "\003"
ssh
ssh
ssh
独立したstdin、stdout、stderr、ttyがあります。。
これまでに送信するたびに、または
^C
単に印刷されます。\cc
\003
可能性:
リモート側にはttyがないため、
^C
SIGINTに「変換」する行規則はなく、プログラムは実際に見える形式(たとえば)に「印刷します」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セッションに送信されます。