使用 ssh2 遇到的问题
发布于 6 年前 作者 y5ma 3931 次浏览 来自 问答

问题描述:

  1. 最近想通过node.js来ssh到远端server, 于是参考了ssh2的官网写法,使用时发现,多次调用后,出现了memory leak…
  2. 感觉conn.end()并没有被终止,每次调用都带着上一次的结果,比如第10次调用的时候,就会打印10条 “ console.log(‘Client disconnected’); ”

报错内容:

2018-2-24 17-00-22.png

2018-2-24 17-00-36.png

场景描述

  1. 远程server登录时先输入root密码,所以在stream.on(‘data’)里加了 “if”去匹配 STDIN data 的关键词,成功后输入root 密码
  2. 输入“who”指令,匹配要的关键字后,执行stream.close()退出
  3. 实测中,指令都是被执行成功的

代码如下:

"use strict";
var sshClient = require('ssh2').Client;
var conn = new sshClient();

module.exports.captureWhoAmI = function(targetIp)  {

    var retryMaxTimes = 30;
    var connection1 = {
        host: "10.99.143.66",
        port: 22,
        username: 'username',
        password: 'password'
    };

    conn.on('ready', function () {
        console.log('Client connected to :' + targetIp);
        var num = 0;
        conn.shell(function (err, stream) {
            if (err) {
                console.log(err)
            }
            stream.on('close', function (code, signal) {
                stream.end();
                conn.end();
            }).on('data', function (data) {
                num += 1;
                if (num >= retryMaxTimes) {
                    console.error('Too many times, giving up to capture!!!');
                    stream.close();
                }
                var dataString = data.toString();
                if (dataString.indexOf("Password:") != -1) {
                    stream.write("rootPassword\n");
                    stream.write("who\n");
                }
                if (dataString.indexOf("user") != -1) {
                    stream.close();
                }
                console.log("conn num:" + num + ":" + data);
            }).stderr.on('data', function (data) {
                console.log('STDERR: ' + data);
            });
        })
    }).on('end', function() {
        console.log('Client disconnected');
    }).connect(connection1);
}

希望大家帮忙指点一下,多谢。

1 回复

Emitter.setMaxListeners(n): “By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. This is a useful default that helps finding memory leaks. Obviously, not all events should be limited to just 10 listeners. The emitter.setMaxListeners() method allows the limit to be modified for this specific EventEmitter instance. The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.”

截图上的错误:

  1. 对同一特定事件的监听,已经超过10次,爆出emitter警告
  2. ssh2中open channel 超过允许的通道数,或者说之前开的channel还没来得及被关闭

3.“var conn = new sshClient();” 写在了封装函数的外面,每次的调用都是在对同一个实例做操作

我的修改:

  1. 把封装函数captureWhoAmI ,写成异步调用,return new Promise(…), 并使用promise.each来多次调用它
  2. 把“var conn = new sshClient();”写在封装函数里面,每次调用都产生一个新的实例,使之互不影响
  3. 考虑连接的机子可能会有超时,未开启等现象,设置错误监听, conn.on(‘error’, …);

这样就可以实现多次调用了。

搜索之后,感觉ssh2库的使用者不多… 大家能分享一下都用哪些ssh的库吗,还是 不喜欢用node.js来ssh?

参考link: https://github.com/mscdex/ssh2/issues/480 http://blog.csdn.net/llmys/article/details/52880464

回到顶部