
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
)。