How to get path of nodejs executable on runtime - node.js

I have to execute a node command within another node process as shown below:
require('child_process').exec (`${<path of current node executable>} someModule`);
How can i retrieve the node executable path on runtime to execute this command.

process.execPath should be what you require.
process.argv0 is not alway pointed to node binary.
As the in the official Node document.
The process.argv0 property stores a read-only copy of the original value of argv[0] passed when Node.js starts.
In the example of the official document, it demo the case that process.argv0 is not the node binary. customArgv0 is for exec's -a flag.
$ bash -c 'exec -a customArgv0 ./node'
> process.argv[0]
'/Volumes/code/external/node/out/Release/node'
> process.argv0
'customArgv0'
If you are trying to execute another node app, how about taking a look at child_process.fork?
You code then should be as follows.
// fork()'s first argument should be the same as require();
// except that fork() executes the module in a child process
require('child_process').fork(`someModule`);
As stated in document, fork() use the same node binary as process.execPath, or you can specify other node binary to execute the module.
By default, child_process.fork() will spawn new Node.js instances
using the process.execPath of the parent process. The execPath
property in the options object allows for an alternative execution
path to be used.

Related

How to get specific node PID in Node-Red?

I am using Node-Red V2.2.2. I would like to restart an specific node of the flow after an error is triggered in it.
I have managed to restart the full flow getting node-red process id. After modifying: settings.js in my .node-red folder:
functionGlobalContext: {
// os:require('os'),
'pid': process.pid
},
I am able to get general process pid from a function node:
var General_pid = context.global.pid
And kill and restart the global process from an Exec node sending General_pid in msg.payload :
Being comando.sh:
#!/bin/bash
taskkill //PID $1 //F
sleep 4
node-red
But i am unable to do this with specific nodes inside the node-red flow.
Almost all info i have searched relied on Status node to get node specific pid,
but in my case, this is the Status node structure (no PID in there):
I have also tried to get PID based on status.source.id using:
RED.nodes.getNode(id);
But RED.nodes is undefined (altough RED is defined, but it only shows functions on print)
Any idea on how to be able to get the node PID to kill it and restart it? I could do it from an Exec node, but if there is an easier way even better.
You don't.
Nodes are not separate processes that can be restarted independently of Node-RED. (While some nodes may fork a new process, e.g. a python script, Node-RED has no access to this and it is all handled inside the node in question)
You have 2 choices:
You can trigger a restart of the deployed flow by making a HTTP call to the /flows Admin API with the header set to reload. Assuming the node with the failure is well written then it should restart cleanly.
Restart all of Node-RED as you are already

force http.globalAgent.keepAlive = true

I have this node CLI tool that consumes all my network's NAT (network address translation) address ports whenever it runs because the node tool creates a connection per outbound http request. The tool doesn't finish the job because the NAT gateway blocks the tool from opening any more outbound ports after the node tool exceeds the limit.
I could set http.globalAgent.keepAlive, but the problem is that this node CLI tool execs to other modules so I would have to set http.globalAgent.keepAlive in all those sub modules as well. Is there a way I can force http.globalAgent.keepAlive everywhere without changing code in every sub-execed node tool?
The node command supports a --require flag which preloads a module (or several modules) before executing file passed to node.
Because of the require cache, if a module imports the http module and sets http.globalAgent.keepAlive = true then any other module that imports http will be importing http from the require cache with http.globalAgent.keepAlive = true.
Therefore, the key is to override the system's node command to --require a module that sets http.globalAgent.keepAlive = true. Whenever the CLI tool execs node the script runs instead and imports the override module first. The require cache will be pre-populated with http and the desired settings for that node process.
A script like the following will pass through any arguments to node and load the overriding module any time a call to node occurs.
#! /bin/sh
exec node_bin --require /path/to/module "$#"
You'll also need to move the original node binary to something like node_bin and insert the above script as the new "node" binary.

How to use pm2 with a nodejs app that uses readline for taking command line input?

I have a Node.js app that uses the node's native readline to be able to take command-line inputs.
When launching the app with pm2, the command-line input is unavailable.
Any ideas how to solve this issue? Other than using systemd and creating an init script myself?
Use pm2 to attach to your process and you will see readline, clearline and cursorTo working as expected.
First get your process id with:
$ pm2 id {your-process-name}
[ 7 ]
Let's say it's 7:
$ pm2 attach 7
if you check the pm2 website they clearly mention the following line: Advanced, production process manager for Node.js. So using it in this context is unnecessary as all pm2 does is start your 'node' process and allows you to manage it, the simple way is to use command line args while starting the process.
for example:
I myself use commander for this purpose. it manages all my command line arguments (u can see its usage). and with pm2 i use it like following:
pm2 start server.js --name production -- --env dev -p 3458
notice -- before --env, it is used to separate pm2 arguments from the arguments you want to supply to your process
p.s.
PM2 has more complex usage than this, in the terms of process management, i myself use it for production level deployment. If you want to take input from a user every time s/he starts your app, then you should stick with using node command only

Run NodeJS application without environment variable

I have a node application that I run on a Linux Server (CentOS 6.5) by setting my environment with a bash script
env_nodejs.sh
#!/bin/bash
PATH=$PATH:/opt/nodejs/node-v6.9.4-linux-x64/bin
export PATH
So that I can
# . ./env_nodejs.sh
# node /var/www/html/application/app.js
That all works fine but if I do the following in a separate script
run_app.sh
#!/bin/bash
$COMMAND=/opt/nodejs/node-v6.9.4-linux-x64/bin/node
$SITE=/var/www/html/application/app.js
nohup $COMMAND $SITE > /tmp/nodeapp.log &
This runs the node server and app but with errors that seem to be related to npm
Error: Failed to lookup view "control/users" in views directory "/views"
I have a feeling this is because the environment is not set but is there a way to run it correctly without the environment or to pass additional parameters for the npm location?
It seems like it's trying to find the files in "/views" which is a top level directory in your file system.
If that is the case then it's not PATH but PWD that's in fault here.
Make sure that when you define where to look for the views in your app, instead of saying 'views' or './views' you use path.join(__dirname, 'views') instead.
You first need to require path with: var path = require(path);
Of course this is just my guess as you didn't include any part of your source code that you have problem with.

Read command line arguments passed to node.js using pm2

I'm aware about how to pass variables to node.js using pm2. But how do I read them? process.argv doesn't contain it.
This is what I'm referring to.
Passing environment variables to node.js using pm2
UPDATE
pm2 start file_name.js -- -my_port 8080 is the right way to do it. process.argv will contain the arguments.
But running pm2 describe file_name still shows args -3000 which is a cached value.
Restarting the system gives me the argument that was passed last before restart, which was 3000 in my case.
I think you're confusing :
node_args
node_args list ["--harmony", "--max-stack-size=1024"] arguments given to node when it is launched
Those are node executable options, like --harmony or --debug=7001. For more informations see node --help
args
args list ["--enable-logs", "-n", "15"] arguments given to your app when it is launched
Those are your script arguments. In a json declaration it's the arg property but within command line the syntax is:
pm2 start app.js -- arg1 arg2
Those should be available in process.argv.
Reference
From the Node.js doc about process.argv:
An array containing the command line arguments.
It does not contain environment variables. You can access the ENV_VARIABLE environment variable using
process.env.ENV_VARIABLE
See this answer.

Resources