転送に ssh を使用しているときにターミナル割り当てによりファイルが壊れる

転送に 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 の割り当てによって出力が変わるのはなぜでしょうか?

答え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.

それを言うと割り当てる1つの疑似端末、リモート側のプロセスは接続が「実際の」端末であることを認識でき、接続が対話型であるため追加のメッセージを送信します。シェルの初期化では、端末モードを設定することもできます。これは を使用して確認できますstty -a。端末モードは、翻訳するキーボード入力とホスト間、およびホストから端末に送信されるテキスト間:

  • それなし初期化中、接続は端末ではないため、変換は行われません。
  • 初期化すると、端末は改行 ( \n) を復帰と改行 (0x0d、0x0a) に変換します。また、(ほとんどのユーザーの場合) タブをスペースに変換します。

記載されている効果は翻訳それがなければ、あなたの相互の作用セッションは画面上で「階段状」になり、使用できなくなります。

シェルは追加情報も出力しますが、単一のコマンドの場合は、提案@kbaは誤解を招く恐れがあるため、シェルは通常送信しませんプロンプト、そして前述のようなSSH制御は~C以下に適用されます。入力それよりも出力

ターミナルで実行する場合、ssh は接続を閉じるときにもメッセージを出力します。ただし、これは標準エラーに書き込まれます。

答え2

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|

私の場合、違いは0d 0a各改行の前の 2 バイトだけですが、もっとある可能性があります (Linux の行の改行は だけです\nが、ターミナルでは と の両方が取得されます\r\n)。

関連情報