在 textarea 中显示 ssh2 stdout 和 stderr
display ssh2 stdout and stderr in textarea
我正在构建一个 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" 这样的简单命令时,它起作用了,我将在我的文本区域中显示标准输出结果。
但是当 shell 脚本 returns 同时包含 stdout 和 stderr 时,或者如果 stdout 是大量文本,由于这个错误,我没有将所有内容都传递到我的 ejs 页面认为:错误:发送后无法设置headers。
我的问题是:只有当脚本完全执行时,如何才能将 stdout 和 stderr 都发送到我的 ejs 页面?我试图通过连接所有标准输出输出来构建一个 "stdout" 变量,但它似乎不起作用...
有人可以帮我吗?
非常感谢
假设进程最终自行结束并且它不会输出大量数据,您可能只是缓冲数据然后在进程关闭时渲染:
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);
真的应该有一个return
:
if (err)
return res.send(err);
以防止进一步执行错误。
我正在构建一个 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" 这样的简单命令时,它起作用了,我将在我的文本区域中显示标准输出结果。
但是当 shell 脚本 returns 同时包含 stdout 和 stderr 时,或者如果 stdout 是大量文本,由于这个错误,我没有将所有内容都传递到我的 ejs 页面认为:错误:发送后无法设置headers。
我的问题是:只有当脚本完全执行时,如何才能将 stdout 和 stderr 都发送到我的 ejs 页面?我试图通过连接所有标准输出输出来构建一个 "stdout" 变量,但它似乎不起作用...
有人可以帮我吗?
非常感谢
假设进程最终自行结束并且它不会输出大量数据,您可能只是缓冲数据然后在进程关闭时渲染:
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);
真的应该有一个return
:
if (err)
return res.send(err);
以防止进一步执行错误。