我正在通过 fork/exec 从 OSX/Linux-C++ 应用程序调用 ssh (OpenSSH) 来创建动态端口转发。这是使用批处理模式 (-o BatchMode=yes) 和提供给 ssh 的私钥 (-i 选项) 完成的。SSH 调用本身不会打开 shell (-N 选项)。
这是我的完整 SSH 调用:
ssh -N -D 9000 -o BatchMode=yes -i /path/to/private-key user@host
我希望尽快继续我的申请,所以我必须查明 ssh 是否成功创建了通道。SSH 本身只有在出现问题时才会返回。
我有没有可能检测到端口转发成功?
当然我可以等到 SSH 打开端口,但我正在寻找更优雅的解决方案。另一个解决方案是检查 SSH 的日志 (-v) 等待“进入交互式会话”,但这对我来说听起来不太方便。
答案1
使用该-f
选项ssh
将进入后台(即fork
在父进程中退出),因此您只需完成waitpid
原始操作ssh
,然后您就知道(基于退出状态)连接失败或端口转发已设置。
答案2
我想我找到了另一个(也是黑客式的)解决方案。当使用以下命令启动 SSH 时
ssh -S /some/domain/socket -M ...args... host
只有成功建立连接后,它才会创建控制域套接字。所以我必须等待域套接字出现在文件系统中。这仍然不太好,但这听起来比等待网络套接字出现更可靠。
有趣的是,这也可以用于找出主控的 PID(参见 R.. 的答案)。使用
$ ssh -S /some/domain/socket -O check host
Master running (pid=25503)