Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在文本区域显示ssh2标准输出和标准输出_Javascript_Jquery_Node.js_Express_Ssh - Fatal编程技术网

Javascript 在文本区域显示ssh2标准输出和标准输出

Javascript 在文本区域显示ssh2标准输出和标准输出,javascript,jquery,node.js,express,ssh,Javascript,Jquery,Node.js,Express,Ssh,我正在构建一个node.js应用程序来管理服务器。 在这个应用程序中,我可以创建一些shell脚本,并通过单击按钮在服务器上执行它们 以下是我在routes.js文件中对此操作的内容: app.get('/exec', isLoggedIn, function(req, res) { var url = require('url'); var url_parts = url.parse(req.url, true); var query = url_parts.query;

我正在构建一个node.js应用程序来管理服务器。 在这个应用程序中,我可以创建一些shell脚本,并通过单击按钮在服务器上执行它们

以下是我在routes.js文件中对此操作的内容:

app.get('/exec', isLoggedIn, function(req, res) {

  var url = require('url');
  var url_parts = url.parse(req.url, true);
  var query = url_parts.query;

  var Server         = require('../app/models/server');
  var Script         = require('../app/models/script');
  var async          = require('async');
  var scriptId       = query.scriptId;
  var userId         = query.userId;
  var serverId       = query.serverId;

  var stdout = "";
  var stderr = "";

  async.parallel({
    servers: function(callback){
      Server.find({"_id" : serverId}).exec(callback);
    },
    scripts: function(callback){
      Script.find({"_id" : scriptId}).exec(callback);
    }
  }, function(err, results) {
    if (err)
      res.send(err);

      var selectedServer = results.servers;
      var selectedScript  = results.scripts;

      var serverIp       = selectedServer[0].serverDetails.serverAddress;
      var serverPort     = selectedServer[0].serverDetails.serverPort;
      var serverUsername = selectedServer[0].serverDetails.serverUsername;
      var scriptContent  = selectedScript[0].scriptDetails.scriptContent;

      var Connection   = require('ssh2');
      var conn         = new Connection();
      conn.on('ready', function() {
        //console.log('Connection :: ready');
        conn.exec(scriptContent, function(err, stream) {
          if (err) throw err;
          stream.on('exit', function(code, signal) {
            //console.log('Stream :: exit :: code: ' + code + ', signal: ' + signal);
          }).on('close', function() {
            //console.log('Stream :: close');
            conn.end();
          }).on('data', function(data_out) {
            console.log('STDOUT: \n' + data_out);
            stdout = stdout + data_out;
            res.render('execresults.ejs', {
              stdout : stdout
            });
          }).stderr.on('data', function(data_err) {
            console.log('STDERR: \n' + data_err);
          });
        });
      }).connect({
        host: serverIp,
        port: serverPort,
        username: serverUsername,
        privateKey: require('fs').readFileSync('id_rsa')
      });

      conn.on('error', function(e) { console.log("Connection failed or timed out")});

    });

  });
它工作正常,我在控制台中有执行结果。但是我想在ejs页面的两个文本区域中显示stdout和stderr结果

问题是,当我运行一个简单的命令,如“uptime”,它的工作,我会有stdout结果显示在我的文本区

但是当shell脚本同时返回stdout和stderr时,或者如果stdout是大量文本,我没有将所有内容都传递到我的ejs页面,因为这个错误,我认为:error:发送后无法设置头

我的问题是:只有当脚本完全执行时,如何才能将stdout和stderr发送到我的ejs页面?我试图通过连接所有标准输出来构建一个“标准输出”变量,但它似乎不起作用

有人能帮我吗


非常感谢

假设流程最终自行结束,并且不会输出大量数据,您可能只需缓冲数据,然后在流程关闭时进行渲染:

conn.exec(scriptContent, function(err, stream) {
  if (err)
    return res.send(err);

  var stdout = '',
      stderr = '';
  stream.on('close', function() {
    conn.end();
    res.render('execresults.ejs', {
      stdout: stdout,
      stderr: stderr
    });
  }).on('data', function(data) {
    stdout += data;
  }).stderr.on('data', function(data) {
    stderr += data;
  });
});
第二,

if (err)
  res.send(err);
应该有一个
返回值

if (err)
  return res.send(err);

为了防止进一步执行错误。

亲爱的ssh2创建者,非常感谢它工作得非常完美:)!我想问你:这种方式是在服务器上执行shell脚本的最佳方式,还是使用sftp上传脚本然后执行脚本更好?非常感谢!我不认为有“最好的方法”,这完全取决于你的需要和什么最适合你。我的意思是,如果脚本不是静态的,那么我认为上传、调用exec然后从服务器上删除文件是不值得的。如果它是一个永不更改的脚本,那么只需上传一次并在exec中调用它可能会更有利,因为您传输的字节数更少(但如果它是一个小脚本,那么性能影响可能可以忽略不计)。无论哪种方式,您都会得到相同的输出。