[英]How do you create a terminal instance within a NodeJS child process?
I am setting up a discord channel to function as an SSH terminal. 我正在设置一个discord通道以用作SSH终端。 A NodeJS server will provide the connection. NodeJS服务器将提供连接。 A custom command will spawn a new terminal instance, which can then be used as a shell. 定制命令将产生一个新的终端实例,然后可以将其用作外壳程序。
I don't know how to spawn a terminal within a child process. 我不知道如何在子进程中生成终端。 I have tried using the screen and bash commands to no avail. 我尝试使用screen和bash命令无济于事。
I am using CentOS 7. 我正在使用CentOS 7。
// Code For Discord
var $discord = {
currentInterface: null,
send: (data) => {
/* some code that sends data to a discord channel */
},
receive: (data) => {
// Send Data To Terminal
if ($discord.currentInterface) {
$discord.currentInterface.send(data);
} else {
$discord.send('**Error:** Terminal has not been spawned.');
}
},
command: (name, args) => {
// Recieve Discord Commands
switch (name) {
case 'spawn':
$discord.currentInterface = $interface();
break;
}
}
};
// Create Interface
var $interface = function () {
// Define object
let x = {
terminal: child_process.spawn('screen'),
send: (data) => {
// Send Input to Terminal
x.process.stdin.write(data + '\n');
},
receive: (data) => {
// Send Output to Discord
$discord.send(data);
}
};
// Process Output
x.terminal.on('stdout', (data) => {
x.receive(data);
});
// Process Errors
x.terminal.on('stderr', (error) => {
x.receive(`**Error:**\n${error}`);
});
// Return
return x;
};
The problem lies with creating the terminal itself. 问题在于创建终端本身。 How do you create an SSH-style shell within a child process? 如何在子进程中创建SSH样式的shell?
I'd take a look at the documentation for child_process.execFile . 我来看看child_process.execFile的文档。 There's an option to set the shell on, but it's disabled by default. 有一个选项可以设置外壳,但是默认情况下它是禁用的。
There's also this approach if you want to try setting up a batch script. 如果您想尝试设置批处理脚本,也可以使用这种方法。 This is set up for windows and the answer isn't set up for passing arguments, but you should be able to adapt it fairly easily. 这是为Windows设置的,而答案不是为传递参数而设置的,但是您应该能够轻松地对其进行调整。
After realizing how much of an idiot I really am, I found a solution... 在意识到我到底是个白痴之后,我找到了解决方案...
// Import Modules
const fs = require('fs');
const child_process = require('child_process');
// Create Interface
var interface = {
terminal: child_process.spawn('/bin/sh'),
handler: console.log,
send: (data) => {
interface.terminal.stdin.write(data + '\n');
},
cwd: () => {
let cwd = fs.readlinkSync('/proc/' + interface.terminal.pid + '/cwd');
interface.handler({ type: 'cwd', data: cwd });
}
};
// Handle Data
interface.terminal.stdout.on('data', (buffer) => {
interface.handler({ type: 'data', data: buffer });
});
// Handle Error
interface.terminal.stderr.on('data', (buffer) => {
interface.handler({ type: 'error', data: buffer });
});
// Handle Closure
interface.terminal.on('close', () => {
interface.handler({ type: 'closure', data: null });
});
Usage... 用法...
interface.handler = (output) => {
let data = '';
if (output.data) data += ': ' + output.data.toString();
console.log(output.type + data);
};
interface.send('echo Hello World!');
// Returns: data: Hello World!
interface.send('cd /home');
interface.cwd();
// Returns: cwd: /home
interface.send('abcdef');
// Returns: error: bin/sh: line 2: abcdef: command not found
interface.send('exit');
// Returns: exit
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.