ssh
を使用して、以下を使用してリモートファイルを解凍しました。
ssh Host "cat file.tgz" | tar xf -
これは完全に正常に機能します。ただし、強制コマンドで遊んでいるときに、pty-allocationによってコマンドの出力が変わることに気づきました。
ssh Host -T "cat file.tgz" >first_file
ssh Host -t "cat file.tgz" >second_file
ここでは、最初のファイルは問題ありませんが、2番目のファイルは壊れています。
Ptyの割り当てが出力を正確に変更するのはなぜですか?
ssh
マニュアルページを読むと役立ちます。
-T Disable pseudo-tty allocation.
-t Force pseudo-tty allocation. This can be used to execute arbi‐
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
allocatea pseudo-tty に指示すると、リモート側のすべてのプロセスは、接続が「実際の」端末であることを認識でき、接続はインタラクティブであるため、追加のメッセージを送信します。シェルの初期化では、ターミナルモードを設定することもできます。これは、stty -a
を使用して検査できます。ターミナルモードは、キーボードエントリとホスト間、およびホストからターミナルに送信されるテキスト間で変換するために使用されます。
\n
)をキャリッジリターンとラインフィード(0x0d、0x0a)に変換します。また、(ほとんどのユーザーにとって)タブをスペースに変換します。説明されている効果は、translationに対するものです。それがないと、インタラクティブセッションが画面全体に「階段状」になり、使用できなくなります。
シェルも追加情報を出力する場合がありますが、単一のコマンドの場合、シェルは通常プロンプトを送信しないため、@ kbaによる suggestion は誤解を招く可能性があります。上記の~C
などのsshコントロールは、outputではなくinputに適用されます。
ターミナルに実行しているとき、sshは接続を閉じるときにもメッセージを出力します。しかし、それは標準エラーに書き込まれます。
Ptyの割り当てが出力を正確に変更するのはなぜですか?
リモート側(端末が割り当てられている)は、ローカル端末の制御文字を「挿入」するためです( 基本的にC0およびC1制御コード )。また、ローカル側はターミナルではなくファイルであるため、それらをそのファイルにダンプするだけです。
SSHは、必要なものを推測するために最善を尽くしています(stdinがTTYでない場合、-tt
スイッチを追加しない限りリモートTTYを割り当てません)。このオプションには理由があり、バイナリ転送が必要な場合は、端末がファイルを台無しにしたくない場合があります。
この動作は、小さなファイルを転送してから16進ダンプするだけで確認できます。
$ ssh -t Host "cat test" > /tmp/test.t
$ ssh Host "cat test" > /tmp/test
$ hexdump -C /tmp/test
00000000 0a 2a 20 46 72 69 20 46 65 62 20 31 32 20 32 30 |.* Fri Feb 12 20|
00000030 6d 3e 20 33 2e 34 2e 31 2d 31 0a 2d 20 4e 65 77 |m> 3.4.1-1.- New|
$ hexdump -C /tmp/test.t
00000000 0d 0a 2a 20 46 72 69 20 46 65 62 20 31 32 20 32 |..* Fri Feb 12 2|
00000030 6f 6d 3e 20 33 2e 34 2e 31 2d 31 0d 0a 2d 20 4e |om> 3.4.1-1..- N|
私にとっての違いは、すべての新しい行の前の2バイト0d 0a
だけですが、もっとあるかもしれません(Linux行の改行は\n
だけですが、ターミナルは両方の\r\n
を取得します)。