How to send command to child process nodejs - node.js

I am making an application that handles java commands and want to send java command to my child spawn process how can i achieve this
const {
spawn
} = require('child_process');
// Start child process
var child = spawn('java', ['-server', '-Xms1G', `-Xmx${document.getElementById('ram').value}G`, `-jar`, `${jarname}`], {
cwd: `${jarfolder}`
});
child.stdout.on('data', (data) => {
$("ol").append(`<li>${data}</li><br>`);
});
child.stderr.on('data', (data) => {
$("ol").append(`<li>${data}</li><br>`);
});
child.on('error', (error) => console.log(`error: ${error.message}`));
child.on('exit', (code, signal) => {
if (code) $("ol").append(`<li>Process exit with code: ${code}</li><br>`);
if (signal) $("ol").append(`<li>Process killed with signal: ${signal}</li><br>`);
});
demo code
example i have a button that calls a function and
function test(){
var command=document.getElementsById("command").innerHTML;
// send the command to terminatal

Related

How to catch error while using fork child process in node?

I am using the fork method to spawn a child process in my electron app, my code looks like this
'use strict'
const fixPath = require('fix-path');
let func = () => {
fixPath();
const child = childProcess.fork('node /src/script.js --someFlags',
{
detached: true,
stdio: 'ignore',
}
});
child.on('error', (err) => {
console.log("\n\t\tERROR: spawn failed! (" + err + ")");
});
child.stderr.on('data', function(data) {
console.log('stdout: ' +data);
});
child.on('exit', (code, signal) => {
console.log(code);
console.log(signal);
});
child.unref();
But my child process exits immediately with exit code 1 and signal, Is there a way I can catch this error? When I use childprocess.exec method I can catch using stdout.on('error'... Is there a similar thing for fork method? If not any suggestions on how I can work around this?
Setting the option 'silent:true' and then using event handlers stderr.on() we can catch the error if any. Please check the sample code below:
let func = () => {
const child = childProcess.fork(path, args,
{
silent: true,
detached: true,
stdio: 'ignore',
}
});
child.on('error', (err) => {
console.log("\n\t\tERROR: spawn failed! (" + err + ")");
});
child.stderr.on('data', function(data) {
console.log('stdout: ' +data);
});
child.on('exit', (code, signal) => {
console.log(code);
console.log(signal);
});
child.unref();

run a few node.js web servers from within a node.js application

I would like to control a few web sites using a UI to start and stop them, changing the ports that the different web server's listen to.
PM2 is a command line utility to manage node sites, but does not have a user interface that I can supply my customer.
How can I run a node.js web site from within another node.js web application.
The following node.js code does not seem to do the work.
const { exec } = require('child_process');
....
exec('node app.js', (err, stdout, stderr) => {
if (err) {
console.log(`err: ${err}`);
return;
}
// the *entire* stdout and stderr (buffered)
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
note: regular linux commands instead of the 'node app.js' command work as expected.
Got the following code to work in case you want to run the same:
This is the code on the server that will spawn a new web server.
app.get('/start', ( req, res ) => {
var node = spawn('node', ['app.js &'], { shell: true });
node.stdout.on('data', function (data) {
console.log('stdout: ' + data.toString());
});
node.stderr.on('data', function (data) {
console.log('stderr: ' + data.toString());
});
node.on('exit', function (code) {
console.log('child process exited with code ' +
code.toString());
});
// Notify client
res.status(200).send( {} );
});
The simplest alternative would be to keep a collection of ExpressJS instances and create/destroy them as needed within NodeJS:
const express = require("express");
var app1 = express();
app1.use("/", function(req, res){ res.send("APP 1"); });
var app2 = express();
app2.use("/", function(req, res){ res.send("APP 2"); });
// start them
var server1 = app.listen(9001);
var server2 = app.listen(9002);
// close the first one
server1.close();
// port 9001 is closed
// port 9002 is still listening
However, if you need to spawn independent processess, you could have:
const { spawn } = require("child_process");
// Prevent Ctrl+C from killing the parent process before the children exit
process.on("SIGINT", () => {
console.log("Terminating the process...");
if (runningProcesses > 0) {
setTimeout(() => process.exit(), 3000);
} else {
process.exit();
}
});
function asyncSpawn(command, parameters = []) {
return new Promise((resolve, reject) => {
runningProcesses++;
console.log(command, ...parameters, "\n");
spawn(command, parameters, {
stdio: "inherit"
})
.on("close", code => {
if (code)
reject(new Error(command + " process exited with code " + code));
else resolve();
})
.on("exit", error => {
runningProcesses--;
if (error) reject(error);
else resolve();
});
});
}
And launch new processes like this:
asyncSpawn("node", ["server.js", "--param1"])
.then(() => console.log("DONE"))
.catch(err => console.error(err));

Executing terminal command in different sessions with nodejs

I want to execute shell command with a nodejs script. And I have a problem about it
As nodejs documentation says;
const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
This works great.
But what if I want to run a command which is kind a endless and I want to run another command.
For example;
const { spawn } = require('child_process');
const simpleServer = spawn('python', ['-m', 'SimpleHTTPServer', '1234']);
simpleServer.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
simpleServer.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
simpleServer.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
gulper.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
gulper.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
gulper.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
Is there any way to do it with different sessions?
You can not run them seperately. You have to use Promise or a tool for async in NodeJS.

child_process.spawn doesn't emit any events

I'm trying to run ripgrep from my Node app and am seeing a strange behavior with child_process.spawn: none of the events fire and the app never finishes (is stuck somewhere inside the spawn call):
import { spawn } from 'child_process';
async function run() {
await spawnWrapper('rg', ['-F', '"demo"'], { cwd: __dirname });
}
export function spawnWrapper(command, args, options) {
return new Promise((resolve, reject) => {
let stdout = '';
let stderr = '';
const child = spawn(command, args, options);
console.log('spawn wrapper');
child.on('close', (code, signal) => {
console.log('close');
resolve({ code, signal, stdout, stderr });
});
child.on('error', (error) => {
console.log('error');
(error as any).stderr = stderr;
reject(error);
});
child.on('exit', (code, signal) => {
console.log('exit');
resolve({ code, signal, stdout, stderr });
});
child.stdout.setEncoding('utf8');
child.stderr.setEncoding('utf8');
child.stdout.on('data', (data) => {
console.log('stdout data');
stdout += data;
});
child.stderr.on('data', (data) => {
console.log('stderr data');
stderr += data;
});
});
}
I only get "spawn wrapper" in the console, no other events. I've never seen this behavior with other binaries, maybe it's something with ripgrep but still, shouldn't I be getting at least some hints by Node? Any suggestions on how to debug this?
It was caused by ripgrep waiting for input which was not obvious to me (on command line, it just executes straight away). Details here: https://github.com/BurntSushi/ripgrep/issues/410

How to execute exe of different machine from my machine in node.js

We are building an application in node js with electron. There is another software which is installed in all other machines.Now in my node js application i want to launch those software on there respective machines.Is it Possible?
You could do this via commands and a child process via spawn.
See â–¶NodeJs API Docs
On Windows
const { spawn } = require('child_process');
const bat = spawn('cmd.exe', ['/c', 'my.bat']);
bat.stdout.on('data', (data) => {
console.log(data.toString());
});
bat.stderr.on('data', (data) => {
console.log(data.toString());
});
bat.on('exit', (code) => {
console.log(`Child exited with code ${code}`);
});
Linux
const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
Below code worked as charm for me.
var cmd = require('node-cmd');
cmd.get('WMIC /node:"ABC-XXXXXXX" process call create "C:\\Setup\\app7.exe"',function(err, data, stderr){
console.log('err:', err)
console.log('stderr:', stderr)
})
Remote machine name : ABC-XXXXXXX
Path of exe on remote machine: C:\Setup\app7.exe

Resources