返回

SSH远程尾随的怪异行为:揭开背后的谜团

Linux

尾随的黑魔法:揭秘 SSH 远程尾随的奥秘

导言

系统管理中不可或缺的一项任务是远程监控日志文件。为了实现这一点,Linux 提供了一个强大的工具——tail,它可以实时显示文件末尾的内容。然而,在使用 tail 从远程机器获取日志时,可能会遇到一些令人头疼的行为。本文将深入探究这些行为背后的原因,并提供一些行之有效的解决办法。

问题

当我们尝试同时运行两个 tail 命令来监控远程机器上的 stdout 和 stderr 时,可能会发现第二个 tail 命令无法正常工作。来看看具体问题

ssh <remote> 'tail /tmp/tmp.gLxtGhFRts/.stdout & tail /tmp/tmp.gLxtGhFRts/.stderr >&2 &'
---contents of stdout---

在这种情况下,只有 stdout 被正确显示,而 stderr 却没有任何输出。

原因分析

要理解这种奇怪的行为,我们需要了解 SSH 和 tail 的工作原理。

  • SSH: SSH(安全外壳协议)是一种加密协议,用于在两台计算机之间建立安全连接。它提供了三种管道:stdin、stdout 和 stderr。当在后台运行命令时,SSH 会保持这些管道处于打开状态,直到命令完成。
  • Tail: tail 命令通过持续读取文件末尾的内容来工作。当它以后台模式运行时,它会将文件符附加到管道(通常是 stdout)。

当在后台运行第一个 tail 命令时,它会附加到 stdout 管道,并开始读取 /tmp/tmp.gLxtGhFRts/.stdout 文件。然而,当运行第二个 tail 命令时,就会出现问题。

第二个 tail 命令试图将自身附加到 stderr 管道,但此时管道已经被第一个 tail 命令占用了。因此,第二个 tail 命令无法读取文件,从而导致没有输出。

解决办法

有几种方法可以解决这个问题:

  • 使用显式等待: 在第一个 tail 命令后添加 wait 命令,它将等待该命令完成并关闭管道。这将允许第二个 tail 命令成功附加到 stderr 管道。
ssh <remote> 'tail /tmp/tmp.gLxtGhFRts/.stdout & tail /tmp/tmp.gLxtGhFRts/.stderr >&2 & wait'
  • 使用重定向: 将 stderr 输出重定向到 stdout,这样两个 tail 命令都可以读取同一个管道。
ssh <remote> 'tail /tmp/tmp.gLxtGhFRts/.stdout & tail /tmp/tmp.gLxtGhFRts/.stderr >&1 &'
  • 使用多个 SSH 会话: 打开两个单独的 SSH 会话,一个用于每个 tail 命令。这样可以确保每个命令都有自己的管道。

其他奇怪的行为

除了上述问题之外,在使用 tail 从远程机器获取日志时,还可能遇到其他一些奇怪的行为:

  • 尾随文件失败: 当尝试从远程文件尾随时,可能会收到 "No such file or directory" 错误。这可能是由于远程文件权限问题造成的。
  • 输出不完整: 在某些情况下,tail 可能会输出不完整或乱码。这可能是由于网络问题或远程机器上的缓冲区问题造成的。

最佳实践

为了避免遇到这些奇怪的行为,请遵循以下最佳实践:

  • 确保远程文件具有正确的权限。
  • 使用可靠的网络连接。
  • 使用显式等待或重定向来确保第二个 tail 命令能够成功附加到管道。
  • 如果遇到输出问题,请尝试调整远程机器上的缓冲区设置。

结论

使用 SSH 远程尾随日志文件时遇到奇怪行为可能会令人困惑。通过了解 sshtail 的工作原理,我们可以理解这些行为背后的原因并找到合适的解决方法。通过遵循最佳实践,可以确保可靠和有效的远程日志监控。

常见问题解答

  1. 为什么第一个 tail 命令会阻止第二个 tail 命令?
    • 因为 SSH 管道已经被第一个 tail 命令占用了。
  2. 如何使用显式等待来解决这个问题?
    • 在第一个 tail 命令后添加 wait 命令。
  3. 重定向 stderr 输出到 stdout 有什么好处?
    • 这样两个 tail 命令都可以读取同一个管道。
  4. 为什么我可能会收到 "No such file or directory" 错误?
    • 这可能是由于远程文件权限问题造成的。
  5. 如何避免输出不完整或乱码?
    • 使用可靠的网络连接并调整远程机器上的缓冲区设置。