一尘不染

如何将“代码”值捕获到变量中?

node.js

我正在使用以下代码使用nodejs和ssh2模块在Linux机器上重置密码:

// FILE * ./workflow/ssh.js

var Client = require('ssh2').Client;
var conn = new Client();

// var opts = require('optimist')
//     .options({
//         user: {
//             demand: true,
//             alias: 'u'
//         },
//     }).boolean('allow_discovery').argv;

// Definition of reset password;

var resetPassword = function(user, host, loginUser, loginPassword){

var command = 'echo -e "linuxpassword\nlinuxpassword" | passwd '+ user;

conn.on('ready', function() {
  console.log('Client :: ready');
  conn.exec(command, function(err, stream) {
    if (err) throw err;
    stream.on('close', function(code, signal) {
      console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
      conn.end();
      return(code);
    }).on('data', function(data) {
      console.log('STDOUT: ' + data);
    }).stderr.on('data', function(data) {
      console.log('STDLOG: ' + data);
    });
  });
}).connect({
  host: host,
  port: 22,
  username: loginUser,
  password: loginPassword
});
};

exports.resetPassword = resetPassword;

我正在从另一个模块(如下所示的test.js)调用resetPassword密码功能。

var ssh = require('./workflow/ssh.js');

result = ssh.resetPassword('test122', '192.168.0.101', 'root' , 'password');
console.log(result)

但是console.log说“未定义”。尝试使用process.nextTick,但没有运气。请帮忙。


阅读 237

收藏
2020-07-07

共1个答案

一尘不染

欢迎来到node.js中使用异步操作进行开发的世界。最初学习node.js时,这是一个非常常见的错误(也是此处StackOverflow的常见问题)。异步操作将在将来完成一些不确定的时间,与此同时,其余代码将继续运行。实际上,您的resetPassword()函数可能在流完成之前且在resetPassword结果可用之前返回。

因此,您不能直接从resetPassword函数返回结果,因为该函数在结果准备好之前就返回了。相反,您将必须传递回调并在调用回调时获取结果,并且此函数的调用者将必须使用回调而不是直接返回的结果。您可以这样实现:

// FILE * ./workflow/ssh.js

var Client = require('ssh2').Client;
var conn = new Client();

// var opts = require('optimist')
//     .options({
//         user: {
//             demand: true,
//             alias: 'u'
//         },
//     }).boolean('allow_discovery').argv;

// Definition of reset password;

var resetPassword = function(user, host, loginUser, loginPassword, callback){

var command = 'echo -e "linuxpassword\nlinuxpassword" | passwd '+ user;

conn.on('ready', function() {
  console.log('Client :: ready');
  conn.exec(command, function(err, stream) {
    if (err) {
        callback(err);
        return;
    }
    stream.on('close', function(code, signal) {
      console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
      conn.end();
      callback(null, code);
    }).on('data', function(data) {
      console.log('STDOUT: ' + data);
    }).stderr.on('data', function(data) {
      console.log('STDLOG: ' + data);
    });
  });
}).connect({
  host: host,
  port: 22,
  username: loginUser,
  password: loginPassword
});
};

exports.resetPassword = resetPassword;

然后,您可以像这样使用它:

var ssh = require('./workflow/ssh.js');

ssh.resetPassword('test122', '192.168.0.101', 'root' , 'password', function(err, code) {
    if (!err) {
        console.log(code);
    }
});

PS从您的原始代码来看,它也并没有真正帮助您从异步回调中抛出。该异常仅发生在任何触发异步回调的node.js基础结构中,而不会返回到原始代码。这就是为什么您的代码也已更改为通过回调传达错误的原因。

根据node.js约定,回调函数至少包含两个参数。第一个参数是一个错误代码,null如果没有错误,则应为错误代码;如果有错误,则为适当的错误代码或错误对象。然后,第二个参数(以及您想要的其他任何参数)传达了一个成功的结果。遵循该约定非常有用,因为它既与node.js在其他地方的处理方式一致,又与某些机械错误处理(例如,将接口修改为使用promises时所做的处理)兼容。

2020-07-07