So that the exit will be shown as it goes out and not suddenly you should use spawn
instead of using exec
. I think it fits more to what you want to achieve. If you want to understand the difference between the two functions you can visit this link .
To be shown in real time you must use socket.io
, it is much more reliable than using GET requests at intervals to get what the command is printing and you can use it as a transport to start executing them.
Here I put a demo that sends the commands from any client and the output is reflected in all the others that are connected. I send the command using the same socket but you can modify it and use POST if you want.
Since you do not specify if you can use other frameworks, use it using only node.js and socket.io.
var http = require('http'),
fs = require('fs'),
url = require('url'),
child = require('child_process');
var fileStream = fs.readFileSync('cmd.html'),
myCommand = 'cmd.exe',
myArgs = ['/?'];
var server = http.createServer(function (req, res) {
if (url.parse(req.url).pathname === '/') {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(fileStream);
} else {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('Not found');
}
}).listen(3000);
function executeCommand(command, args) {
var toExec = command || myCommand,
theArgs = args ? args : (command ? [] : myArgs);
var cmd = child.spawn(toExec, theArgs);
cmd.stdout.on('data', function (data) {
io.emit('output', data.toString());
});
cmd.stderr.on('data', function (data) {
io.emit('output', data.toString());
});
cmd.on('error', function (err) {
io.emit('output', err.message);
});
cmd.on('close', function (code) {
io.emit('Process exited with code ' + code);
});
}
var io = require('socket.io')(server);
io.on('connection', function(socket) {
socket.on('command', function(cmd) {
var c = cmd.split(' ');
executeCommand(c[0], c.slice(1));
});
});
console.log('Server running at http://127.0.0.1:3000/');
And this is the cmd.html
file sent to the client
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Live command</title>
</head>
<body>
<div id="dashboard"
style="width: 100%; height: 300px; overflow: auto; background-color: black; color: white; border: gray solid 3px">
</div>
<div style="margin-top: 30px">
<label for="command">Command:</label>
<input id="command" type="text">
<button id="send" type="button">Execute</button>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
window.onload = function () {
var socket = io('http://localhost:3000');
var console = document.getElementById('dashboard');
var button = document.getElementById('send');
var command = document.getElementById('command');
socket.on('output', function (data) {
var newLine = document.createElement('p');
newLine.innerHTML = data;
console.appendChild(newLine);
});
button.addEventListener('click', function () {
socket.emit('command', command.value);
});
};
</script>
</body>
</html>