Node.js child processes to run python code not responding - node.js

I have an Express Node.js application, but I want to run python code (send data and receive results)
but when I'm testing it using postman still loading and I don't have any response.
my node.js code
router.get('/name', callName);
function callName(req, res) {
var exec = require("child_process").exec;
var process = exec('python',["./hello.py",
req.query.firstname,
req.query.lastname
] );
process.stdout.on('data', function(error,data) {
console.log('stderr: ', error);
res.send(data.toString());
} )
}
python code
import sys
# Takes first name and last name via command
# line arguments and then display them
print("Output from Python")
print("First name: " + sys.argv[1])
print("Last name: " + sys.argv[2])
# Save the script as hello.py
thank you #nijm I found the solution
first The child_process.exec method doesn't accept the command arguments as an array (like child_process.spawn does).
second,
u must have python installed on ur machine.
third
u must have python file in a public folder (in my case uploads folder)
all these steps don't mention in any tutorial or an example about How to call a Python function from Node.js
at the end of the day, my code is
router.get('/name', callName);
function callName(req, res) {
var exec = require("child_process").exec;
exec(`python uploads/hello.py ${req.query.firstname} ${req.query.lastname}`, (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
}
python code
import sys
# Takes first name and last name via command
# line arguments and then display them
print("Output from Python")
print("First name: " + sys.argv[1])
print("Last name: " + sys.argv[2])
# Save the script as hello.py

The child_process.exec method doesn't accept the command arguments as an array (like child_process.spawn does), try this (untested):
var exec = require("child_process").exec;
exec(`python ./hello.py ${req.query.firstname} ${req.query.lastname}`, (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});

Related

How to run function in child process in Node.js

I've been able to successfully run commands using the exec() command. However, I'd like to leave a process running and continue to run commands on the open process, then close on app exit. Take this generic code:
const { exec } = require("child_process");
exec("XR_Command -i 192.168.0.100 -f /ch/01/on | kill", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
I would like to keep the XR_Command process active so that I can issue commands to the active process. So, basically I would like to do this:
> XR_Command -i 192.168.0.100
> /ch/01/on
> /ch/02/on
> /ch/03/on
I cannot for the life of me figure out how to make this function properly by referencing the existing child process. Thanks!
Okay, so after a day I figured out two main problems I was running in to, here is my working code:
const { spawn } = require('child_process');
let Command = spawn('X_Control', ['-i', '192.168.0.1']);
Command.stdout.pipe(process.stdout);
Command.stderr.pipe(process.stderr);
Command.stdin.write('some command\n');
Command.on('error', function(err) {
console.error(err);
});
Command.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
Command.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
Issue 1: My application command was X_Control -i 192.168.0.1, every space needs to be quoted separately as Command = spawn('X_Control', ['-i', '192.168.0.1']); This took me a while to track down.
Issue 2: Command.stdin.write('some command\n'); is how I execute commands on my running application, and it must be followed by \n in order to execute the command.

How to handle mysql command-line password prompt using exec function

I don't know how id pipe the password variable in the exec function.
I've tried running it, but no prompt appears.
const {user,password,database} = require('./config.js');
const { exec } = require('child_process');
const comm = `mysql -u ${user} -p ${database} < ${QUERY_PATH} `
exec(comm)
I guess the only part missing is to use the callback, as recommended by Node in https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback .
Replace:
exec(comm)
by:
exec(comm, (error, stdout, stderr) => {
console.log(stdout);
})
This way, you need to type the password manually. If you don't want to type the password manually (not recommended, mySQL warns about safety concerns using this second method), then the code would be:
const comm = `mysql -u${user} -p${password} ${database} < ${QUERY_PATH}`
If you want to check what is the error happening to you, and that's how I debugged, use the callback function to log the errors:
exec(comm, (error, stdout, stderr) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});

Node.js Child process can not catch windows exe file's output

I want to use child_process.spawn to execute a windows exe file and catch it's output.
When I use command line to run a thirdparty exe file (says A.exe), it will print some logs to the cmd window. Like this:
C:\> A.exe
some outputs...
some more outputs...
However, when I spawn it in node.js, using this
import childProcess from 'child_process';
const cp = childProcess.spawn('A.exe');
cp.stdout.on('data', data => console.log(`stdout: ${data}`));
cp.stderr.on('data', data => console.log(`stderr: ${data}`));
There is no outputs at all.
I think the outputs of A.exe is not to the stdout (so I can never get data by listening stdout), but I don't know how it print logs when running from command line.
Any help would be greatly appreciated.
On Unix-type operating systems (Unix, Linux, macOS) child_process.execFile() can be more efficient because it does not spawn a shell. On Windows, however, .bat and .cmd files are not executable on their own without a terminal, and therefore cannot be launched using child_process.execFile(). When running on Windows, .bat and .cmd files can be invoked using child_process.spawn() with the shell option set, with child_process.exec(), or by spawning cmd.exe and passing the .bat or .cmd file as an argument (which is what the shell option and child_process.exec() do). In any case, if the script filename contains spaces it needs to be quoted.
// On Windows Only ...
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}`);
});
Maybe give this approach a go:
var childProcess = require('child_process');
childProcess.exec('A.exe', function(error, stdout, stderr) {
if (error != null) {
console.log('error occurred: ' + error);
} else {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
}
});
// OR
var cp = childProcess.spawn('A.exe');
cp.stdout.on('data', (data) => {
console.log('stdout: ' + data.toString());
});
cp.stderr.on('data', (data) => {
console.log('stderr: ' + data.toString());
});

Run Bash-Script within Electron App using child_process.exec

I'm struggling with running a bash-script within main.html.
const exec = require("child_process").exec;
// Execute bash script
exec("/c/workspace/_edu_zone/Proxy_Manager/filemover.sh", shellCallback);
// Callback
function shellCallback(error, stdout, stderr) {
console.log(error, stdout)
}
I'm always getting the error: no such file or directory. What am i doing wrong?
Any help is highly appreciated.
change
/c/workspace/_edu_zone/Proxy_Manager/filemover.sh
to
c:/workspace/_edu_zone/Proxy_Manager/filemover.sh
or
your could try using node-powershell to execute the command directly
const shell = require('node-powershell')
let ps = new shell({
executionPolicy: 'Bypass',
noProfile: true
});
function lunchnode() {
process.stdout.write('logging');
ps.addCommand('node run.js')
ps.invoke()
.then(function (output) {
process.stdout.write(output)
}).catch(function (err) {
process.stdout.write(err)
ps.dispose()
})
}

Enumerate system drives in nodejs

Is there a way to retrieve the drive name of all logical drives on a computer ?
I've looked at the fs api, but from there I can only enumerate the files and directories of a given directory.
I'm not sure what you mean by "drive name". If you mean drives in the form of \\.\PhysicalDriveN, I faced the same problem and implemented this module that works in all major operating systems:
https://github.com/resin-io/drivelist
For Windows, you get information such as:
[
{
device: '\\\\.\\PHYSICALDRIVE0',
description: 'WDC WD10JPVX-75JC3T0',
size: '1000 GB'
},
{
device: '\\\\.\\PHYSICALDRIVE1',
description: 'Generic STORAGE DEVICE USB Device',
size: '15 GB'
}
]
If you targeting on Windows, you could try this:
This solution base upon the idea from this post.
I wrap it with promise.
var spawn = require("child_process").spawn
function listDrives(){
const list = spawn('cmd');
return new Promise((resolve, reject) => {
list.stdout.on('data', function (data) {
// console.log('stdout: ' + String(data));
const output = String(data)
const out = output.split("\r\n").map(e=>e.trim()).filter(e=>e!="")
if (out[0]==="Name"){
resolve(out.slice(1))
}
// console.log("stdoutput:", out)
});
list.stderr.on('data', function (data) {
// console.log('stderr: ' + data);
});
list.on('exit', function (code) {
console.log('child process exited with code ' + code);
if (code !== 0){
reject(code)
}
});
list.stdin.write('wmic logicaldisk get name\n');
list.stdin.end();
})
}
listDrives().then((data) => console.log(data))
Test it, you will see the result like:
["c:", "d:"]
Based on Edwin Lees answer:
const child = require('child_process');
child.exec('wmic logicaldisk get name', (error, stdout) => {
console.log(
stdout.split('\r\r\n')
.filter(value => /[A-Za-z]:/.test(value))
.map(value => value.trim())
);
});
Output: ['C:', 'D:'] etc.
How about using the DiskPart command? Does running diskpart list in the command line give you the output you need? If so you can execute this in node using child_process.exec
var exec = require('child_process').exec
var cmd = 'diskpart list'
exec(cmd, function(err, stdout, stderr) {
if (err) {
console.log('error running diskpart list command')
console.log(err)
return
}
console.log('stdout data')
console.log(stdout)
console.log('stderr data')
console.log(stderr)
})
+1 for #Bagherani's downgrade suggestion!
I am using Electron React Boilerplate v4.0 and could not get drivelist to load. I downgraded to drivelist#5.2.12 and it works for my needs.

Resources