Running two node processes inside a shell script - javascript

I am a total beginner in shell scripting.
I have a node js program, and an API, which uses mongoDB. So the API uses express and is linked to my routes and schemas - all I have to do in order to start the API server is run node app.js
However, I also have my main program, which polls specific urls that the user adds through the database, and then saves the data that is returned from the poll request in the database. This happens every 'x' seconds, therefore I always open the mongo connection when the poll happens, and close it as soon as it finishes it. So in order to run this program, I need to run node main.js
The app.js seems to just open the mongo connection once, when the program is run.
So my question is - can I link them together somehow by writing a bash script so I can start both of the processes together and end them when needed?
I tried doing this:
#!/usr/bin/bash
# declare STRING variable
STRING="Starting node processes"
#print variable on a screen
echo $STRING
node misrepo/app.js
node misrepo/main.js
However this only starts the app.js, and does not run my main.js application.
Any help would be appreciated as I am just trying to figure this out from googles help!

Good answer by Markus,
nevertheless, I need a add a little comment and due to lack of reputation, I need to create an answer.
It is better to start both processes in background (caused by the &) and wait for both processes to finish. Otherwise, it seems that both processes are finished while you only wait for the second command. That might cause trouble in processing output of both commands.
#!/usr/bin/bash
# declare STRING variable
STRING="Starting node processes"
#print variable on a screen
echo $STRING
node misrepo/app.js&
node misrepo/main.js&
# wait until both background processes finish
wait
Best,
Frank

Service management is tricky and there are tools built specifically for it. It's best if you don't reinvent the wheel in bash.
Use forever or pm2 to manage a service.
npm install forever -g
forever start misrepo/app.js
Put them in your script
#!/bin/sh
forever start misrepo/app.js
forever start misrepo/main.js
You can also include these commands (or your script) in the scripts section of your package.json
{
"scripts": {
"start": "forever start misrepo/app.js && forever start misrepo/main.js"
}
}
Then npm start will start your app. stop and restart are also standard.
If your doing this on a server, then use the native service manager to manage each service. This is likely to be systemd if you're on linux.

To start two programs in parallel you can do the following:
#!/usr/bin/bash
# declare STRING variable
STRING="Starting node processes"
#print variable on a screen
echo $STRING
node misrepo/app.js & node misrepo/main.js
This will start node with misrepo/app.js and immediately another instance of node with misrepo/main.js.
In your example the script blocks until node misrepo/app.js finishes execution and only then starts node misrepo/main.js

this is maybe too late but hope this will help somebody who is searching for the answer.
#!/bin/bash
//enter in to first folder
cd /var/www/html/demo/
//check the files(if no need remove ls
ls
//this will start first node process and after & enters to the next directory
node app.js & cd /var/www/html/demo1
//to ensure the cd command from before line
ls
//starts second node server
node server.js ;
//executes the bin file
exec bash

Related

Easy ways to quit and restart an entire script?

I have a Discord bot that I'm writing a restart function for. I want to be able to run one command that will not only stop the script, but kill and restart it, so I can implement updates quickly. I've realized that the Discord API is not sufficient for this so I haven't added it to the tags. The simplest way I can think of is by using two scripts that call each other.
Every resource I've found references either a module (?) called PM2 or a programming language called VBScript. I do not want to mess around with a module that automatically reboots every single time I save, and I especially don't want to try learning a new language.
Here is my pseudocode showing what I'm aiming for:
[bot.js]
function reboot() {
runFile(`./reboot.js`)
}
[reboot.js]
kill (`./bot.js`)
runFile(`./bot.js`)
The result I'm hoping for is for bot.js to run reboot.js. Reboot.js will then quit bot.js and run it again. Then reboot.js will close. I don't care about any processes already running on bot.js.
Of course, if there are even simpler ways to do this, please let me know. I need as much simplicity as I can get.
PM2 is a process manager and would do the trick for you.
It's easily installed: npm install pm2 -g
Start your bot: pm2 start bot.js --name "Discord Bot"
Code-wise, you'll want to simply kill the process. PM2, being a process manager, will restart it for you.
I've figured it out. I used the child-process module built into node.js.
[bot.js]
var cp = require('child_process');
function reboot() {
var ls = cp.spawn('node', ['reboot.js']);
client.destroy()
}
[full contents of reboot.js]
var cp = require('child_process');
var ls = cp.spawn('node', ['bot.js']);
(posting all this for fellow noobs to use)
Edit: Note that after restarting, console outputs no longer work, as it's running from reboot.js rather than directly from the terminal.
I'm not familiar with Discord bots, but if you want to start, kill and restart processes programmatically in NodeJS then you want to look into the child_process module.
https://nodejs.org/api/child_process.html#child_process_child_process

Node.js application with Heroku Scheduler having a Shebang line issue

I am trying to deploy a small Node.js application to Heroku, and then have the Heroku Scheduler run the application every 10 minutes. Our customers former supplier who built this application also hosted it on Heroku, so there should be no need to change anything in the sourcecode, that I have received. Nevertheless I am getting the following error from the Heroku log.
2018-05-09T07:26:07.710882+00:00 app[api]: Starting process with command `fetch` by user scheduler#addons.heroku.com
2018-05-09T07:26:11.124833+00:00 heroku[scheduler.2653]: Starting process with command `fetch`
2018-05-09T07:26:11.718182+00:00 heroku[scheduler.2653]: State changed from starting to up
2018-05-09T07:26:13.647479+00:00 heroku[scheduler.2653]: State changed from up to complete
2018-05-09T07:26:13.629258+00:00 heroku[scheduler.2653]: Process exited with status 126
2018-05-09T07:26:13.542885+00:00 app[scheduler.2653]: bash: /app/bin/fetch: /usr/local/bin/node: bad interpreter: No such file or directory
Apparently there's an issue with the 'Shebang' line in my fetch file which runs my index.js file:
#!/usr/local/bin/node
var path = require('path');
require(path.join(__dirname, '../index')).start();
I am rather new to Node.js and Javascript, so I'm not sure I fully understand the purpose of the 'Shebang' line. But I'm guessing it is pointing to a wrong location or something like that? How do I figure out, what to change in this line?
Shebang line tells which interpreter to use to run the file. Error you receive tells that node is not installed in location shebang points to. Using #!/usr/bin/env node usually works.
You should not have a need for any "shebang" line in your "fetch" file.
I suggest you simply remove the #!/usr/local/bin/node line, and specify the following as your Heroku Scheduler command:
node <path_to_fetch.js>
That should get heroku scheduler to launch your node.js app in a one-off dyno, provided you have a node.js buildpack in your app.
Use the instructions here to check if you have a node.js buildpack in your app, and to add it if necessary.
That said, if you really want to run your app with a "shebang", change it to #!/usr/bin/env node. In that case, omit the word node in your Heroku scheduler command.

Run code once for a single version of a Node.js based CLI

I have written a CLI in Node.js, that you can globally install using npm. Now I want to run a specific piece of code the first time a user runs my CLI. But it should only run once.
My question is: How could I detect that the CLI is run for the very first time?
Of course, I could write a file into the user's home directory, and if it exists, skip code execution. This would be pretty simple.
But now things get slightly more complicated: I want this check to be re-run when the user updates the CLI to a new version. So, again, I could write a file into the user's home directory, and store the versions in it, for which I have run the "once"-code block.
But this again means that every time the user runs the CLI it has to open the file, parse it, look for the version, and so on. I fear that this could negatively impact startup performance.
Is there a better way to solve this?
I have a stupid idea, treat this as an academic example of hacky metaprogramming. Create a script named script.js:
var fs = require('fs');
if(!process.env.firstRun){
var content = fs.readFileSync("script.js", "utf8");
fs.writeFileSync('script.js', 'process.env.firstRun=true;\r\n' + content, 'utf8');
console.log('first run');
} else {
console.log('next run');
}
The script simply overwrites itself by adding an additional flag declaration at the beginning if it's not set. Otherwise it goes the other path:
λ node .\script.js
first run
λ node .\script.js
next run
λ node .\script.js
next run
The above was just for fun. For production code you should go for a configuration file as you proposed. Reading single small file is not a big deal, according to this method it takes <0.5ms in my setup (I5 processor, SSD drive), so it's definitely a way to go.

Run Windows Node.js script in background when the user logins by setting a Run key

I'm running on Windows Server 2012R2.
I have a node.js script which I want to run when the user performs logins.
To do this I'm setting the command to run in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run registry path.
I set this command:
/path/to/node/node /path/to/node/script args
This works fine, but it will spawn a terminal showing the command output, while I'd like to run this command in background and detached from any command terminal.
I tried to replace the previous command with:
start /b /path/to/node/node /path/to/node/script args
but in this case there is no evidence that the script was even started.
I also tried to wrap the following command in a .bat script:
start \b node script args
set the name of the script in the Run key: in this case I can see terminal flash but then the script is not running anymore (I suppose that the script is executed but then it is stopped as soon as the parent process is terminated).
I want to avoid to convert the script in a windows service, as long as a simpler solution is possible.
A solution not using the Run registry key is also fine, as long as it fulfils my requirement (run a script in background when the user logins).
Actually it's pretty easy , use forever.js module
after installing the module use
"forever start main.js"
It will start running as your background process

"..." in every action in node.js

First I want to clarify that I'm new in node.js and I'm not a linux user, so the cmd isn't my thing.
Every time I try to do something, for example
sudo npm install express#2.6.5 (as it's in a sitepoint ebook example)
or
node example.js (as another tutorial)
Every time, the response is a "..." in the screen (http://www.screencast.com/t/dx6VZhsVtl), so my 3 questions:
Why this happens (I'm missing some configuration or something)?
How to install packages (as the ... is always the response)
When I run a program, I don't have to specify the absolute path, just the file?
It looks like you're trying to run the file example.js, but you're still running a node REPL session (indicated by the >, see the link for more details). Press Control+C a few times to exit to get back to regular terminal (it should show something like username#machineName:).
To run a node file, use node [filename].
To open a node REPL session, simply use node.

Categories

Resources