spawn a command line operation in nodejs without opening console - node.js

I need to execute a command line operation from nodejs program. But I don't want to open console. I need to get result back to a variable. sync-exec module is helping to get result back but it keeps open a console for process execution.
I am sharing small bit of code.
var execSync = require('sync-exec');
var npmGlobalPath = execSync('npm config get prefix');
console.log(npmGlobalPath);
one more thing I want to share. This was happening when I already spawned a child process from parent. Now this code is in child process.

Related

What does the additional JavaScript mean in node document?

Blocking is when the execution of additional JavaScript in the Node.js process must wait until a non-JavaScript operation completes. This happens because the event loop is unable to continue running JavaScript while a blocking operation is occurring.
It means the rest of your JavaScript code, that hasn't been excuted yet. It's blocked from being excuted, until non-JavaScript operation completes.
They explain it in the next section in the documentation: https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/#comparing-code
In the first example:
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read
console.log(data);
moreWork(); // will run after console.log
The additional JavaScript code here is the 2 lines that are blocked by the synchronous file reading, above it. These 2 lines don't get excuted until the file reading is complete:
console.log(data);
moreWork(); // will run after console.log
Tip: when you ask a question, it's best to add sources if your question references another website. In this case: https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/#blocking

Is there a way to store spawn object (child_process) in database and reuse it?

Why I need this?
Client make request to server
Server receive request, starts python script with spawn (child_process)
If python script needs more information to proceed running, I must send user email with link which leads to page with only one input field
When user fill that, I must continue SAME process (running script) and enter that in command line with ls = spawn('command', args) and then ls.stdin.write()
How I can do this? My idea is, to get object from
const { spawn } = require('child_process');
const ls = spawn('command', [args]);
insertInDb(JSON.stringify(ls));
And then use it with
const ls = JSON.parse(databaseInput);
ls.stdin.write(input);
But it doesn't work.
No, but I can't imagine a scenario in which you would want to. What if your user emails back tomorrow? Or next week? Or never? You just have these dangling python processes clogging up your system.
If you're positive you'll get quick feedback you can talk your python script via a shared file descriptor:
const cp = spawn(cmd,args,{
stdio:['pipe','pipe','pipe','pipe']
});
cp.stdio[3].on('data',(data)=>{
// data from python's fd 3
});
cp.stdio[3].write('foobar'); // write to python's fd 3
But you almost certainly should just have two different python scripts.

How to send "CTRL+C" to child process in Node.js?

I tried to spawn child process - vvp (https://linux.die.net/man/1/vvp). At the certain time, I need to send CTRL+C to that process.
I am expecting that simulation will be interrupted and I get the interactive prompt. And after that I can continue the simulation by send command to the child process.
So, I tried something like this:
var child = require('child_process');
var fs = require('fs');
var vcdGen = child.spawn('vvp', ['qqq'], {});
vcdGen.stdout.on('data', function(data) {
console.log(data.toString())
});
setTimeout(function() {
vcdGen.kill('SIGINT');
}, 400);
In that case, a child process was stopped.
I also tried vcdGen.stdin.write('\x03') instead of vcdGen.kill('SIGINT'); but it isn't work.
Maybe it's because of Windows?
Is there any way to achieve the same behaviour as I got in cmd?
kill only really supports a rude process kill on Windows - the application signal model in Windows and *nix isn't compatible. You can't pass Ctrl+C through standard input, because it never comes through standard input - it's a function of the console subsystem (and thus you can only use it if the process has an attached console). It creates a new thread in the child process to do its work.
There's no supported way to do this programmatically. It's a feature for the user, not the applications. The only way to do this would be to do the same thing the console subsystem does - create a new thread in the target application and let it do the signalling. But the best way would be to simply use coöperative signalling instead - though that of course requires you to change the target application to understand the signal.
If you want to go the entirely unsupported route, have a look at https://stackoverflow.com/a/1179124/3032289.
If you want to find a middle ground, there's a way to send a signal to yourself, of course. Which also means that you can send Ctrl+C to a process if your consoles are attached. Needless to say, this is very tricky - you'd probably want to create a native host process that does nothing but create a console and run the actual program you want to run. Your host process would then listen for an event, and when the event is signalled, call GenerateConsoleCtrlEvent.

Close another process from node on Windows

How can I kill a process from node on Windows?
I'm making a updater. It needs close a windows executable (.exe) to download the updates. (The update process is download and overwrite). I read that this is possible with process.kill(pid[, signal])
But, How can I get the PID of the process if I know the name of the process?
According to the documentation, you simply access the property.
process.kill(process.pid, 'SIGKILL');
This is a theoretical, untested, psuedo function that may help explain what I have in mind
exec('tasklist', (err, out, code) => { //tasklist is windows, but run command to get proccesses
const id = processIdFromTaskList(processName, out); //get process id from name and parse from output of executed command
process.kill(id, "SIGKILL"); //rekt
});
Use node-windows to get pid of process you want to kill so that you can call process.kill. The library also provides an api to kill task.

restart node.js application on file change

as you know in node.js if you edit a server-side file, you need to restart the application in order to make for the changes.
Now I was wondering is there a way to do this inside the server, as we know when a file has changed or not(based on last modification date), we only need to re-run the application or restart it or do something that make the changes available without us doing it from the command line.
And we all know how to do this with some Grunt.js(or something like that) or supervisor, but I want to do this without any external package.
thanks alot :)
You can initially have the server startup such that when it ends it start again. In a Bash file it would simply be a recursive function.
function start(){
node index.js
start
}
Or in a batch file a goto statement
:start
node index.js
goto start
Then in your node server when you detect a file change you simply end the process
For watching the files there's modules out there that make it easier. Eg. watch
require('watch').watchTree('./server', process.exit);
You can maybe use this method to watch the files who have to restart server on change :
https://nodejs.org/api/fs.html#fs_fs_watchfile_filename_options_listener
Using cluster.fork to run all code in a child process and setting the master process to fork a new child whenever the previous child exits. Then simply exit the child focibly upon file change, using chokidar.
// Put this at the very beginning of your code
var cluster = require('cluster');
if (cluster.isMaster) {
cluster.on('exit', cluster.fork);
cluster.fork();
return;
}
require('chokidar').watch('./**/*.*').on('change', process.exit);
// Rest of the code here
...

Resources