時々私は次のようなことをします
ssh user@Host Sudo thing
また、sshはデフォルトでは疑似ttyを割り当てないことに注意してください。なぜそうではないのですか? ssh
をssh -t
にエイリアス化すると、どのようなメリットが失われますか?
主な違いは、interactivityの概念です。コマンドをローカルでスクリプト内で実行するのと似ていますが、コマンドを自分で入力するのと同じです。リモートコマンドはデフォルトを選択する必要があり、非対話型が最も安全であるという点で異なります。 (そして通常最も正直です)
Ctrl-c
ブレークは通常、sshコマンドのループを即座にブレークさせますが、制御シーケンスはリモートサーバーに送信されます。これにより、sshコマンドの制御が終了したとき、次のsshコマンドが始まる前に確実にキーストロークが到達するように、「打つ」必要があります。Cronなどの無人スクリプトでssh -t
を使用しないように注意します。リモートコマンドに入力のために対話的に動作するように要求する非対話型シェルは、あらゆる種類の問題を要求します。
独自のシェルスクリプトで端末の存在をテストすることもできます。新しいバージョンのbashでSTDINをテストするには:
# fd 0 is STDIN
[ -t 0 ]; echo $?
ssh
をssh -t
にエイリアス化すると、行末で余分なキャリッジリターンが得られることが期待できます。それはあなたには見えないかもしれませんが、そこにあります。 ^M
にパイプすると、cat -e
として表示されます。次に、特にその出力をデータベースに挿入する場合は、この制御コードが変数に割り当てられないようにするための追加の労力を費やす必要があります。これは以前と同じbashテストですが、STDOUTの場合です。
# fd 1 is STDOUT
[ -t 1 ]; echo $?
これらの問題を回避することは可能ですが、それらを回避するスクリプトの設計を忘れることになります。私たち全員がある時点で行います。チームメンバーは、このエイリアスが設定されていることを認識または覚えていない場合があり、エイリアスを使用するスクリプトを作成すると問題が発生します。
ssh
からssh -t
へのエイリアスは、 最小の驚き ;の設計原則に違反することになる場合がほとんどです。人々は予期しない問題に遭遇し、それらの原因を理解していない可能性があります。
他の回答で言及されていない利点の1つは、疑似端末なしでを操作する場合、SSHエスケープ文字です。 ~C
などはサポートされていません;これにより、プログラムがこれらのシーケンスを含む可能性のあるバイナリファイルを転送することが安全になります。
疑似端末を使用してバイナリファイルをコピーします。
$ ssh -t anthony@remote_Host 'cat /usr/bin/free' > ~/free
Connection to remote_Host closed.
疑似端末を使用せずにバイナリファイルをコピーします。
$ ssh anthony@remote_Host 'cat /usr/bin/free' > ~/free2
2つのファイルは同じではありません:
$ diff ~/free*
Binary files /home/anthony/free and /home/anthony/free2 differ
疑似端末でコピーされたものは壊れています:
$ chmod +x ~/free*
$ ./free
Segmentation fault
もう一方はそうではありません:
$ ./free2
total used free shared buffers cached
Mem: 2065496 1980876 84620 0 48264 1502444
-/+ buffers/cache: 430168 1635328
Swap: 4128760 112 4128648
これは、データ転送にSSHを使用するscp
やrsync
などのプログラムで特に重要です。これは SCPプロトコルの仕組みの詳細な説明 は、SCPプロトコルがテキストプロトコルメッセージとバイナリファイルデータの混合でどのように構成されるかを説明しています。
-t
フラグが使用されている場合でも、OpenSSH ssh
クライアントは、stdin
ストリームがターミナルでないことを検出した場合、疑似ターミナルの割り当てを拒否することに注意してください。
$ echo testing | ssh -t anthony@remote_Host 'echo $TERM'
Pseudo-terminal will not be allocated because stdin is not a terminal.
dumb
OpenSSHクライアントに-tt
を使用して疑似端末を強制的に割り当てることもできます。
$ echo testing | ssh -tt anthony@remote_Host 'echo $TERM'
xterm
どちらの場合も、stdout
またはstderr
がリダイレクトされるかどうかは(賢明に)気になりません。
$ ssh -t anthony@remote_Host 'echo $TERM' >| ssh_output
Connection to remote_Host closed.
リモートホストでは、次の設定を行う必要があります。
/etc/sudoers
...
Defaults requiretty
須藤なし
$ ssh -T user@Host echo -e 'foo\\nbar' | cat -e
foo$
bar$
そして須藤と
$ ssh -T user@Host Sudo echo -e 'foo\\nbar' | cat -e
Sudo: sorry, you must have a tty to run Sudo
Sudoでは追加のキャリッジリターンを取得します
$ ssh -t user@Host Sudo echo -e 'foo\\nbar' | cat -e
foo^M$
bar^M$
Connection to localhost closed.
解決策は、stty -onlcr
を使用して改行をキャリッジリターン-改行に変換を無効にすることです。
$ ssh -t user@Host stty -onlcr\; Sudo echo -e 'foo\\nbar' | cat -e
foo$
bar$
Connection to localhost closed.
下位互換性について考えます。
Sshの2つの主なモードは、ttyを使用した対話型ログインと、ttyを使用しない指定コマンドです。これらはそれぞれrlogin
とrsh
の正確な機能であるためです。 sshはrlogin
/rsh
機能のスーパーセットを提供して、置き換えとして成功する必要がありました。
したがって、デフォルトはsshが生まれる前に決定されました。 「コマンドを指定したいand get tty」のような組み合わせは、新しいオプションでアクセスする必要がありました。 rsh
を使用していたときとは異なり、少なくともhaveこのオプションを今は喜んでください。暗号化された接続を取得するために役立つ機能をトレードオフしませんでした。ボーナス機能を手に入れました!
man ssh
から:
-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.
これにより、リモートサーバーへの「シェル」のようなものを取得できます。 notを実行するサーバーでシェルアクセスを許可し、SSHを許可する場合(つまり、GithubはSFTPアクセスの既知の例です)、このフラグを使用すると、サーバーが接続を拒否します。
シェルにはすべての環境変数($PATH
など)も含まれているため、スクリプトを実行するには、通常ttyが必要です。