ssh "-f" 在监听 stdout/stderr 时不要在 bash 中回手

ssh "-f" 在监听 stdout/stderr 时不要在 bash 中回手

请看这些:

## Does NOT return to the shell, but Ctrl-C can exit
ssh -S none -fNR 13018:localhost:22 example.com | cat

## Returns to the shell (no "-S none")
ssh         -fNR 13019:localhost:22 example.com | cat

## Returns to the shell (no "| cat")
ssh -S none -fNR 13020:localhost:22 example.com

为什么第一个命令不返回到 shell?我希望它能像另一个一样返回到 shell(就像-f 请求 ssh 在命令执行之前进入后台。)并且存在于我给出的 3 个示例中,并且在重定向其输出时似乎表现不稳定(此处用 表示| cat)。这-S none不是一个相关的选项(特别是这-S none应该是默认行为,因为我没有设置任何 ControlMaster 选项),但它似乎仍然改变了-f.这一切都让我困惑。

有什么方法可以捕获最后一个命令的 stdout/stderr 并让该命令返回到 shell,以便能够根据其输出做出反应?

整个故事:

我想运行 SSH 隧道,并在失败时检查它是否与正在使用的端口有关。在这种情况下,我会尝试另一个端口。我无法使用错误级别,因为它不独特,并且在尝试捕获 stderr 时,我运行了对我来说不清楚的 ssh 行为,它们甚至看起来是假的(使用-S none和不使用它之间不应该有任何区别,因为它是默认值,我检查了我的~/.ssh/config值是空的,并且/etc/ssh/ssh_config没有ControlMaster设置相关选项。)

编辑:

  • 看来我无法重现所描述的第二个示例。进程有时会ssh终止吗有时 cat进程打开管道?

答案1

奇怪的是,我不明白的是为什么你的第二个例子返回到外壳(我无法重现)。

当您运行时ssh -S none -fNR 13018:localhost:22 example.com | cat,ssh 进程将保留在后台。它仍然使管道的写入端打开。因此,cat尚未在其标准输入上看到文件结尾,因此它会继续读取。

Ctrl+C终止cat进程(这是作业中唯一仍在运行的部分,因为后台的 ssh 进程已移至其自己的进程组,并且前台 ssh 进程一旦分叉就会终止)。如果后台 ssh 进程尝试写入其标准输出(由于-N),写入将失败并显示 EPIPE(ssh 阻止 SIGPIPE)。如果您终止了后台 ssh 进程,该cat进程也会退出。

相关内容