SSHサーバーに接続する通常の方法はssh username@ip_address
です。しかし、ユーザーはリモートマシンでプログラムを実行したいだけかもしれません。したがって、プログラム名は、通常の引数ssh username@ip_address <program_name>
の後に続きます。たとえば、ssh username@ip_address ls
です。対話型プログラム(ユーザー入力も出力も提供する)を除いて、その引数は問題ありません。 top
。出力は
TERM環境変数が設定されていません。
つまり、sshdとtopプログラムの間に(疑似)端末が接続されていません。解決策は、引数-t
を追加することです。ここで、コマンド全体がssh -t username@ip_address top
になります。
私の質問は、なぜデフォルトではsshdも疑似端末を使用して非対話型プログラムと通信できないため、対話型プログラムに-t
引数を追加する必要がないのですか?
他の人が言ったように、PTYにはある程度のオーバーヘッドがあることは事実ですが、リモートコマンドの実行時にPTYを使用しない大きな理由は、情報を失うことです。
通常、ssh経由でリモートでコマンドを実行すると、コマンドのstdout
およびstderr
ストリームがローカルのstdout
およびstderr
に送信されます。つまり、それらを個別にリダイレクト/パイプする-例:
$ ssh server ls foo bar
ls: cannot access bar: No such file or directory
foo
$ ssh server ls foo bar > stdout 2> stderr
$ cat stdout
foo
$ cat stderr
ls: cannot access bar: No such file or directory
しかし、PTYを使用する場合、PTYには出力/エラー用の個別のストリームがないため、すべての出力はstdout
に送られます。
$ ssh -t server ls foo bar > stdout 2> stderr
$ cat stdout
ls: cannot access bar: No such file or directory
foo
$ cat stderr
$
ssh
のマニュアルページはこれを説明しています:
ユーザーのIDがサーバーに受け入れられると、サーバーは非インタラクティブセッションで指定されたコマンドを実行するまたはコマンドが指定されていない場合は、マシンにログインしてユーザーは対話型セッションとして通常のシェル。リモートコマンドまたはシェルとのすべての通信は自動的に暗号化されます。
これは機能であり、おそらくrsh
動作の歴史的な理由が原因です。それはかなり合理的です。ほとんどのコマンドは実際にはインタラクティブではなく、PTYを割り当てるのは自由な操作ではありません(20年前に重要でした)。
ssh
は、呼び出しているコマンドがインタラクティブかどうかをどのように判断するとしますか?
この悪夢は、UNIX以外のOSを実行しているマシンにログインできることに気づくと、さらに悪化します。
簡単な解決策はなく、1つのケースをデフォルトにする必要がありました。