web-dev-qa-db-ja.com

転送にsshを使用しているときに、端末の割り当てによってファイルが破損する

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の割り当てが出力を正確に変更するのはなぜですか?

4
michas

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は接続を閉じるときにもメッセージを出力します。しかし、それは標準エラーに書き込まれます。

2
Thomas Dickey

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を取得します)。

0
Jakuje