libssh执行远程命令必须手动构造会话、认证、通道并循环读取标准流;需显式设置超时、主机验证策略、端口及密钥选项;认证失败须重连;每次命令需新建channel并完整走open→exec→read→close流程。
libssh 本身不提供“执行远程命令”的高层封装,必须手动构造会话、认证、通道并处理标准流——直接调用 ssh_channel_request_exec 是唯一可靠路径,别指望类似 Python paramiko 那样的 exec_command 一键函数。
初始化会话与连接前必须显式设置超时和主机验证策略
libssh 默认拒绝连接未知主机,且无默认连接/读写超时,不设会卡死。常见错误是跳过 ssh_options_set 或误用 SSH_OPTIONS_HOST 拼接端口(应单独设 SSH_OPTIONS_PORT)。
- 必须调用
ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &timeout_sec),否则ssh_connect可能永久阻塞 - 若跳过主机密钥验证(如测试环境),需设
ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, ""),而非留空或忽略 - 主机名不能带
ssh://前缀,端口必须用SSH_OPTIONS_PORT单独传整数,不能写在 host 字符串里
密码认证失败常因未调用 ssh_userauth_password 或忽略返回值
libssh 的认证是状态机驱动,ssh_userauth_password 返回 SSH_AUTH_SUCCESS 才算成功;返回 SSH_AUTH_DENIED 后不能重试同一 session,必须断开重连。
- 必须检查返回值:
if (ssh_userauth_password(session, NULL, password) != SSH_AUTH_SUCCESS) - 密码含特殊字符(如
@、/)无需转义,libssh 不解析 URL 格式 - 公钥认证更稳定,推荐用
ssh_userauth_publickey_file,私钥路径必须为绝对路径或确保当前工作目录正确
执行命令后必须主动读取 stdout/stderr 并关闭 channel
ssh_channel_request_exec 仅发起请求,不自动收数据;不循环 ssh_channel_read 会导致命令看似“没输出”,实际已执行但缓冲区滞留。