Answers:
在
ssh host tail -f file
该ssh
客户端连接到sshd
服务器上host
通过TCP连接。sshd
运行tail -f
,其标准输出重定向到管道。sshd
读取来自管道另一端的内容,并将其封装在sshd协议中以发送给ssh
客户端。(使用rshd
,tail
stdout可以直接sshd
用作套接字,但是可以添加加密,并且能够在单个TCP连接上多路复用多个流(例如,用于端口/代理/ X11 /隧道重定向,stderr),因此必须诉诸管道。)
当您按CTRL-C时,SIGINT发送到ssh
客户端。那导致ssh
死亡。死后,TCP连接关闭。因此,上host
,sshd
模具也是如此。tail
不会被杀死,但是它的标准输出现在是另一端没有读取器的管道。因此,下次它向标准输出中写入内容时,它将收到SIGPIPE并死亡。
在:
ssh -t host 'tail -f file'
和是一样的,只是sshd
和之间的通信不是通过管道,tail
而是通过伪终端进行。tail
的stdout是从属伪终端(如/dev/pts/12
),并且在主端进行的任何tail
写操作read
(可能由tty行规程修改)都由客户端sshd
发送并封装到ssh
客户端。
在客户端,使用-t
,ssh
将终端置于raw
模式。特别是,这将禁用终端规范模式和终端信号处理。
所以,当你按下Ctrl+C,而不是客户端的终端线路规范发送SIGINT的ssh
工作,这仅仅发送^C
通过连接字符sshd
并sshd
写道,^C
远程终端的主端。远程终端的线路规则发送SIGINT
给tail
。tail
然后死亡,sshd
退出并关闭连接并ssh
终止(如果它仍然不忙于端口转发或其他操作)。
同样,使用-t
,如果ssh
客户端死亡(例如,如果输入~.
),则连接将关闭并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
-t
,如果ssh
客户端死亡(例如,如果输入~.
),”又是什么~.
?
~.
是您输入的用于断开客户端连接的转义序列。有关man ssh
详细信息,请参见。
您需要在远程端分配终端:
ssh -t user@remote_host tail -f /some/file
甚至
ssh -tt user@remote_host tail -f /some/file
-t
还是-tt
作品。但是我仍然无法理解其真正原因:例如,当我远程调用shell并关闭连接时,shell终止了。但是tail -f
不是。当然,我已经在中阅读了有关-t
option的信息man ssh
,但并没有太大帮助。似乎我不理解某些泛型,如果您建议一些文档阅读它,或者自己解释一下,我将很高兴。谢谢!
sshd
发送SIGHUP
。但是如果没有终端,就不会有终端连接挂断……
SIGHUP
和其他信号,但对此一无所知。
tail -f
,然后打开htop
并发SIGHUP
送给它(按F9
-> 1
-> Enter
),然后tail -f
终止!所以,原因应该有一些不同..
tail
不会做出反应SIGHUP
。问题在于,如果没有伪终端,SIGHUP
**不会发送给tail
。通过在两种情况下都附加strace
,您可以看到这一点tail
。