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

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

私は以下sshを使ってリモートファイルを解凍しました。

ssh host "cat file.tgz" | tar xf -

これは非常にうまく機能します。しかし、forceコマンドを使用すると、pty割り当てがコマンドの出力を変更することがわかりました。

ssh host -T "cat file.tgz" >first_file
ssh host -t "cat file.tgz" >second_file

ここでは、最初のファイルは問題ありませんが、2番目のファイルが破損しています。

ptyの割り当てによって出力が変わるのはなぜですか?

答え1

読むのに役立ちます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.

言うと分配する医者tty、リモート側のすべてのプロセスは、接続が「実際の」端末であることを確認でき、接続が対話型であるため、追加のメッセージが送信されます。シェル初期化中にを使用して確認できる端末モードも設定しますstty -a。ターミナルモードは次の目的で使用されます。翻訳するキーボード入力とホスト間、ホストから端末に送信されるテキスト間:

  • いいえ初期化すると、接続は端末ではないため、変換は行われません。
  • そして初期化中、端末は\n改行文字()をキャリッジリターン改行文字(0x0d、0x0a)に変換します。また、(ほとんどのユーザーの場合)タブを空白に変換します。

説明された効果は次のとおりです。翻訳する。それがなければ、インタラクティブセッションが画面を横切って「階段」になり、使用できなくなります。

シェルは追加情報を印刷することもできますが、単一コマンドの場合提案シェルは通常転送しないため、@kbaは誤解を招く可能性があります。ヒント、上記のSSHコントロールは~C次に適用されます。入力する代わりに出力

端末で実行すると、ssh は接続を閉じるとメッセージも出力します。ただし、これは標準エラーに記録されます。

答え2

ptyの割り当てによって出力が変わるのはなぜですか?

割り当てられた端末があるリモート側では、ローカル端末に制御文字を「注入」するためです(デフォルトでは、C0およびC1制御コード)。ローカル側は端末ではなくファイルなので、そのファイルにダンプします。

-ttSSHは、ユーザーが望むものを推測するために最善を尽くしています(stdinがTTYでない場合は、スイッチを追加しない限りリモート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|

私にとって、違いは0d 0a各改行の前の2バイトにすぎませんが、それ以上があるかもしれません(Linux行は改行専用ですが、\n端末は両方ともインポートされます\r\n)。

関連情報