![使用 tee 在详细模式下通过 SSH 调试 rsync,将 stdout 重定向到日志文件](https://linux22.com/image/713860/%E4%BD%BF%E7%94%A8%20tee%20%E5%9C%A8%E8%AF%A6%E7%BB%86%E6%A8%A1%E5%BC%8F%E4%B8%8B%E9%80%9A%E8%BF%87%20SSH%20%E8%B0%83%E8%AF%95%20rsync%EF%BC%8C%E5%B0%86%20stdout%20%E9%87%8D%E5%AE%9A%E5%90%91%E5%88%B0%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6.png)
我在网络上的某台机器上通过 SSH 执行各种 rsync 操作时遇到问题,失败并出现以下错误:
rsync: connection unexpectedly closed (45482 bytes received so far) [generator]
我找到了类似的帖子(rsync-无法解释的错误),其中一个答案建议以详细模式运行 rsync 使用的 SSH 命令并重定向输出,在我的情况下如下所示:
rsync -av -e 'bash -x -c "ssh -p 22 -vvvv $0 $@ 2>/tmp/rsync-ssh.stderr | tee /tmp/rsync.stdout"' --rsync-path='sudo rsync' "[email protected]:/media/remote_volume/" "/media/local_volume"
此 rsync 命令似乎运行良好一段时间,但最终失败并出现错误:
tee: standard output: Resource temporarily unavailable
我猜测它失败的原因可能与以下问题的答案中描述的类似:为什么这件 T 恤会丢失标准输出?但是,我似乎不清楚应该如何更改 SSH 命令来解决这个问题。
在这种情况下,有人知道如何让 SSH 与 tee 良好配合吗?
答案1
在对问题答案中讨论的解决方案进行了更多的阅读之后,“为什么这件 T 恤会丢失标准输出?",看来关键的变化是将管道替换为重定向到包含否则将被管道传输到的命令的子 shell。(因此,将:替换command1 | command2
为command1 > >( command2 )
:)
这样做的原因是,通过重定向到子 shell,而不是直接进入下一个命令,可以强制子 shell 处理任何EAGAIN
错误代码返回。正如 FreeBSD 留言板消息中所讨论的那样:bin/164947:tee 在写入非阻塞文件描述符时丢失数据(也链接到另一个问题的答案)tee
并且其他系统二进制文件本身在处理重试时可能非常糟糕。
对于rsync
上述命令,以下更改似乎可以解决我原来的问题:
rsync -av -e 'bash -x -c "ssh -p 22 -vvvv $0 $@ 2>/tmp/rsync-ssh.stderr > >( tee /tmp/rsync.stdout )"' --rsync-path='sudo rsync' "[email protected]:/media/remote_volume/" "/media/local_volume"