nodejs在windows下如何与ssh.exe进程通信

新手上路,请多包涵

场景

ssh.exe来自微软编译的openSSH for Windows,也就是Win10自带的ssh命令行工具,直接调用系统自带的也可以。

现在,我要使用nodejs中child_process模块的spawn或execFile等方法运行ssh.exe,并通过stdio进程通信,实现自动输入密码登录的功能。

(备注:不用告诉我使用node-ssh之类的库,那些我知道哈)

代码如下

仅需几行代码:

const path = require('path')
const spawn = require('child_process').spawn

// 通过spawn方法运行ssh.exe
const ssh = spawn('ssh.exe', '-o StrictHostKeyChecking=no -o PasswordAuthentication=yes -P22 root@10.0.0.55'.split(' '))

// 当ssh.exe在输出流中输出内容时,判断如果内容提示输入密码,则向其输入流发送密码
ssh.stdout.on('data', data => {
  process.stdout.write(data.toString()) // 这行竟然无效
  if (/password:/gi.test(data)) ssh.stdin.write('my password') //这行竟然也无效
})

文件结构图:(实际上就只有index.js一个文件,其他ssh.exe等文件可无视,可直接调用系统自带的)
文件结构图

运行结果

失败,没有自动登录

如图:

疑问

如果是通常的exe程序,上述代码的进程通信方式是没有问题的,但是openSSH不知道是何原因,从ssh.stdout.on('data')事件中监听不到root@10.0.0.55's password:这行输出,且使用ssh.stdin.write()向ssh.exe进程发送密码,也没有反应。

请问这是什么原因,有何解决方案实现这个自动登录的功能?
感谢大神解答。

阅读 3.9k
1 个回答

别试了,这个我曾经研究过一段时间。

ssh我怀疑是通过特殊的手法劫持了stdin,你无法通过传统的管道方式喂数据给stdin来实现非交互式。能起作用的目前我所知的只有expect方案,它是完全模拟用户的交互式输入,可以交互ssh,python有个对应的包装实现Pexpect,没查过nodejs有没有类似的类库。

目前社区上普遍采用的ssh非交互式方案是sshpass,它可以帮你实现ssh非交互式,比自己用expect之类的简单的多,著名的ansible, salt-stack之类的工具都是依赖sshpass实现ssh非交互式控制服务器。如果你想实现ssh非交互式,建议你考虑这个方案。

RHEL官方的系统管理员文档也推荐这个工具实现ssh非交互式 https://www.redhat.com/sysadm...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题