Sté*_*las 33
在
ssh host tail -f file
Run Code Online (Sandbox Code Playgroud)
该ssh客户端连接到sshd服务器上host通过TCP连接。sshd运行tail -f时将其标准输出重定向到管道。sshd读取来自管道另一端的内容并将其封装在 sshd 协议中以发送给ssh客户端。(使用rshd,tailstdout 将直接作为套接字,但sshd添加了加密并能够在单个 TCP 连接上多路复用多个流(如端口/代理/X11/隧道重定向、stderr),因此必须求助于管道)。
当您按下 CTRL-C 时,一个 SIGINT 被发送到ssh客户端。这导致ssh死亡。在死亡时,TCP 连接关闭。因此,在host,sshd也会死亡。tail没有被杀死,但它的标准输出现在是另一端没有读取器的管道。因此,下次它向其标准输出写入内容时,它将收到一个 SIGPIPE 并死亡。
在:
ssh -t host 'tail -f file'
Run Code Online (Sandbox Code Playgroud)
这是相同的东西,只是用与管道之中,之间的通信sshd,并tail是经由一伪终端。tail的 stdout 是一个从属伪终端(如/dev/pts/12),并且在主端(可能由 tty 行规则修改)tail写入的任何内容read都由sshd并封装到ssh客户端发送。
在客户端侧,具有-t,ssh把终端raw模式。特别是,这会禁用终端规范模式和终端信号处理。
因此,当您按下 时Ctrl+C,不是客户端的终端线路规则向ssh作业发送 SIGINT ,而是通过^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
Run Code Online (Sandbox Code Playgroud)
使用-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
Run Code Online (Sandbox Code Playgroud)
Hau*_*ing 11
您需要在远程端分配终端:
ssh -t user@remote_host tail -f /some/file
Run Code Online (Sandbox Code Playgroud)
甚至
ssh -tt user@remote_host tail -f /some/file
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11383 次 |
| 最近记录: |