接続が閉じられたときに「tail -f」と呼ばれるリモートで終了する方法は?


24

を実行するとssh user@remote_host tail -f /some/filetail -f /some/filessh接続が閉じられていてもremote_hostで実行し続けることに気付きました!

したがって、いくつかの接続と切断の後、実行数がtail -f /some/file増加します。tail -fSSH接続が閉じられたときに実際に終了する方法は?

回答:


33

ssh host tail -f file

sshクライアントがに接続しsshdているサーバhostのTCP接続を介して。stdoutをパイプにリダイレクトしてsshd実行tail -fします。sshdパイプのもう一方の端から送られてくるものを読み取り、sshdプロトコルにカプセル化してsshクライアントに送信します。(ではrshdtailstdoutは直接ソケットでしたがsshd、暗号化を追加し、単一のTCP接続で複数のストリーム(ポート/エージェント/ X11 /トンネルリダイレクト、stderrなど)を多重化できるため、パイプに頼る必要があります)。

CTRL-Cを押すと、SIGINTがsshクライアントに送信されます。それはssh死にます。死亡すると、TCP接続は閉じられます。したがって、上hostでもsshd死にます。tailは殺されませんが、その標準出力は、もう一方の端にリーダーのないパイプです。そのため、次に標準出力に何かを書き込むときに、SIGPIPEを受け取って死にます。

に:

ssh -t host 'tail -f file'

それは間の通信、代わりにパイプであるということを除いて同じことだsshdとは、tail擬似端末を介して行われます。tail標準出力は、スレーブ疑似端末(等である/dev/pts/12)と何tailがあるの書き込みreadマスター側(おそらくTTYライン規律によって修飾)によってsshdとにカプセル化された送信sshクライアント。

クライアント側で-tsshを使用して、端末をrawモードにします。特に、端末の標準モードと端末の信号処理が無効になります。

それで、あなたは押したときにCtrl+C、代わりに、クライアントの端末回線の規律がにSIGINTを送るsshだけで送信していること、仕事^Cへの接続を介して、文字をsshdしてsshdいることを書き込み、^Cリモート端末のマスタ側へ。そして、リモート端末の回線制御はに送信SIGINTtailます。tailその後sshd、終了し、接続をssh終了して閉じ、終了します(ポート転送などでまだビジーでない場合)。

また、を使用すると-tsshクライアント~.が停止した場合(たとえばを入力した場合)、接続が閉じられて停止しsshdます。その結果、SIGHUPがに送信されtailます。

さて、使用に-tは副作用があることに注意してください。たとえば、デフォルトの端末設定では、\n文字が変換さ\r\nれ、リモートシステムに応じてさらに多くのことが発生する可能性があるためstty -opost、その出力が意図されていない場合は、リモートホストで(出力の後処理を無効にするため)を発行することができますターミナル:

$ ssh  localhost 'echo x' | hd
00000000  78 0a                                             |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000  78 0d 0a                                          |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000  78 0a                                             |x.|
00000002

-t/ を使用する別の欠点は-tt、クライアントでstdoutとstderrが区別されないことです。リモートコマンドのstdoutとstderrの両方がsshクライアントのstdoutに書き込まれます。

$ ssh localhost ls /x  | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1

このような詳細な説明をありがとうございました!私は..私は2つの答えを受け入れることがしたい
ドミトリーフランク・

「with -tsshクライアントが死んだ場合(たとえばを入力した場合~.)」何が~.再びですか?
x-yuri

1
@ x-yuri ~.は、クライアントを切断するために入力するエスケープシーケンスです。詳細man sshを参照してください。
ステファンシャゼラス

11

リモート側で端末の割り当てが必要です:

ssh -t user@remote_host tail -f /some/file

あるいは

ssh -tt user@remote_host tail -f /some/file

1
ありがとう、両方-tまたは-tt作品。しかし、これの本当の理由はまだ理解できません。たとえば、シェルをリモートで呼び出して接続を閉じると、シェルは終了します。しかし、そうでtail -fはありません。もちろん、私はすでに-tオプションについて読んでいますがman ssh、あまり役に立ちませんでした。私はいくつかのジェネリックを理解していないようです、そしてそれについて読むためにいくつかのドキュメントを提案するか、おそらくあなた自身でそれを説明していただければ幸いです。ありがとう!
ドミトリーフランク14年

2
@DmitryFrank私の理解はこれです:接続が切れたら、をsshd送信しSIGHUPます。しかし、誰の端末には、端末の接続ハングアップ...あり得ないではないところ
Hauke Laging

おかげで、私はSIGHUP他のシグナルについて読みますが、それについてはほとんど何も知りません。
ドミトリーフランク14年

fyi:実行しようとしtail -fましたがhtop、開いSIGHUPて(F9-> 1->を押して)送信しEntertail -f終了しました!だから、その理由は、いくつかの異なるはず...
ドミトリー・フランク

3
@DmitryFrankあなたは問題を誤解しています。問題はそれにtail反応しないということではありませんSIGHUP。問題は、擬似端末なしでSIGHUPは「送信されtailない」ということです。両方の場合にアタッチstraceすることでそれを見ることができますtail
ホークレイジング14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.