我在我的项目中编码ssh2模块时遇到了麻烦。我尝试在一个终端上运行多个命令来统治远程Linux系统。例如,"bc"命令为您提供了一个基本的计算器,您可以运行它进行基本操作。但是,当您使用时,这种进程需要处于唤醒状态(它将接受两个或多个输入,并将作为结果给出响应)。
我需要创建一个系统,如工作与websocket和ssh。当websocket接收到命令时,ssh节点需要执行该消息,模块需要通过websocket.send()发送响应
我使用Node.js websocket,ssh2客户端。
下面是我的代码:
#!/usr/bin/node
var Connection = require('ssh2');
var conn = new Connection();
var command="";
var http = require('http');
var WebSocketServer = require('websocket').server;
var firstcom=true;
conn.on('ready', function() {
console.log('Connection :: ready');
// conn.shell(onShell);
});
var onShell = function(err, stream) {
// stream.write(command+'n');
stream.on('data', function(data) {
console.log('STDOUT: ' + data);
});
stream.stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
}
var webSocketsServerPort=5000;
var ssh2ConnectionControl=false;
var server = http.createServer(function (req, res) {
//blahbalh
}).listen(webSocketsServerPort, function() {
console.log((new Date()) + " Server is listening on port:: " + webSocketsServerPort);
});
//console.log((new Date()) + 'server created');
wsServer = new WebSocketServer({
httpServer: server,
// autoAcceptConnections: false
});
wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection from origin ' + request.origin + '.');
var wsconnection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
if(!ssh2ConnectionControl){
conn.connect({
host: 'localhost',
port: 22,
username: 'attilaakinci',
password: '1'
});
ssh2ConnectionControl=true;
console.log('SSH Connected.');
}
wsconnection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
command=message.utf8Data;
//if(firstcom){
// conn.shell(onShell);
// firstcom=false;
//}else{
conn.exec(message.utf8Data,onShell);
//}
wsconnection.send(message.utf8Data);
}
else{
console.log('Invalid message');
}
});
wsconnection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + wsconnection.remoteAddress + ' disconnected.');
});
});
如果你想要一个真正的交互式shell,你应该使用conn.shell()
而不是conn.exec()
。conn.exec()
通常用于执行一行命令,因此它不会在conn.exec()
调用之间保持"shell状态"(例如工作目录等)。
您还应该了解SSH服务器设置的限制,即每个连接允许同时有多少shell/exec请求。我认为OpenSSH服务器的默认限制是10。
这是一个老问题,但是我想提供一个使用sh2shell包装ssh2的替代方法。上面使用的mscdex Shell。下面的示例只介绍了建立ssh连接、运行命令和处理结果。
使用ssh2shell可以在相同的shell会话中在前面命令的上下文中连续运行任意数量的命令,然后返回每个命令的输出(onCommandComplete事件)和/或在使用回调函数断开连接时返回所有会话文本。有关示例和大量信息,请参阅ssh2shell自述文件。还有用于工作代码示例的测试脚本。
var host = {
//ssh2.client.connect options
server: {
host: 120.0.0.1,
port: 22,
userName: username,
password: password
},
debug: false,
//array of commands run in the same session
commands: [
"echo $(pwd)",
command1,
command2,
command3
],
//process each command response
onCommandComplete: function( command, response, sshObj) {
//handle just one command or do it for all of the each time
if (command === "echo $(pwd)"){
this.emit("msg", response);
}
}
};
//host object can be defined earlier and host.commands = [....] set repeatedly later with each reconnection.
var SSH2Shell = require ('ssh2shell');
var SSH = new SSH2Shell(host),
callback = function( sessionText ){
console.log ( "-----Callback session text:n" + sessionText);
console.log ( "-----Callback end" );
}
SSH.connect(callback)
要查看进程级发生的情况,将debug设置为true