Prereload script into node interactive mode - node.js

Is it possibille to run node.exe, pipe a text into it, and continue the interactive session?
I want to create a shortcut bat (or bash) file for editing my database.
Usually this is what I'm doing:
$ node
>var db=require('mydb')
>db.open('myserver')
>//Now I can start access the db
>db.query...
I want to do something like that:
$ node -i perDefinedDb.js
>db.query(.... //I don't want to define the DB each time I run the node.exe
I tried some like that:
echo console.log(a) | node.exe
This is the result:
3
And the program is Finish. I want to continue the node REPL after piping something into.
In Other Words:
I want to be able to use my DB from node REPL, without defining it each time.

Launch the REPL from your js file and you can give the context you want:
const repl = require('repl');
var db = require('mydb');
db.open('myserver');
repl.start('> ').context.db = db;
Now you just have to run this file (node myREPL.js) and you can REPL as usual.

Related

Automate Node.js CLI program from shell script

I and trying to execute a node.js CLI program which takes an input from user to decide the next step.
I am able to start the program by
node index.js
after this I want to send 1 as input. Is there a way I can give input to my node.js program.
My dumb brain came up with following script
--Script.sh--
node index.js
1
2
which obviously didn't work.
Maybe this would work?
Create an answers.txt file with each input on its own line:
first
second
then run the command like this:
node index.js < answers.txt
The < will redirect input to the specified file instead of stdin.
What about:
#!/bin/dash
echo "Type something or 'q' to quit and press Enter!"
while read user_input; do
if [ "$user_input" = 'q' ]; then
break
else
echo "You've typed: ""$user_input"
# do something
# node index.js "$user_input"
fi
done

how to pass shell script variable to node app.js?

I have prepared the shell script to launch the node application (written using express framework). Shell script looks like below-
#!/bin/bash
cd <NODE.JS Project directory>
npm install --save
var1="connect_point1";
var2="connect_point2";
node app.js var1 var2
in app.js have included below lines-
//print process.argv
process.argv.for Each((val, index) => {console.log('${index}: ${val}');});
var cp1=var1;
var cp2=var2;
I am unable to get var1,var2 values which is passed from shell script to use it in node app.js script. Please suggest me correct way to achieve this.
In the log can see the variable var1 and var2 not defined. so issue is when i am trying to pass the shell script variable to node app.js script..pls suggest me how to pass those parameter correctly, so it can be used in ap.js and other subsequent node scripts.
Add a $ sign to your arguments inside bash script to indicate variables.
#!/bin/bash
var1="connect_point1"
var2="connect_point2"
node app.js $var1 $var2
app.js
process.argv.forEach((index, value) => console.log(index, value));
This is the output i see when running the above bash script:
./bash_script.sh
/usr/local/Cellar/node/12.4.0/bin/node 0
/Users/Username/Temp/app.js 1
connect_point1 2
connect_point2 3
here you can see that the argument values you need are located on index 2 and 3:
var cp1 = process.argv[2];
var cp2 = process.argv[3];

I want to run the terminal command n nodejs language

Creating a Nodejs server code, I'd like to turn on a new terminal window and enter a command.
var exec = require('child_process').exec
exec('gnome.terminal', (err,out,stderr) => {
console.log(out)
});`
I'd like to open a new window with the code above and enter a command.
(new) 1 terminal -> command : roslaunch rpliadr_ros rplidar.launch
(new) 2 terminal -> command : roslaunch hector_slam_launch tutorial.launch
Please look up shell.js module.
You can use OpenTerm module. It's do exactly what you want - open terminal, and execute.
It has both functions for individual terminals: ( consider to use them only if you sure they exists in your PATH ).
const { VT } = require('open-term')
VT.linux.xterm('ls -l') // Runs "ls -l" command in xterm.
VT.linux.guake('ls -l') // Runs "ls -l" command in guake.
And configurable function which automatically determines terminal to use:
const { VTexec } = require('open-term')
VTexec('help') // "help" command works both on bash and cmd.

How to get mongo shell output(three dot) for unterminated command

When type a unterminated command in a mongo shell, it will return three dots indicating need more input to complete this command like below:
> db.test.find(
... {
...
I am using nodejs child_process.spawn to create a mongo shell process and listen on its output. I can get the standard and error output from the mongo shell but I can't get the ... output. Below is my nodejs code:
const shell = spawn('mongo', params);
shell
.stdout
.on('data', (data) => {
winston.debug('get output ' + data);
});
shell
.stderr
.on('data', (data) => {
const output = data + '';
winston.error('get error output ', data);
});
I run below code to send command on the shell:
shell.stdin.write('db.test.find(');
I wander why I can't get the ... output on above method. Is it a special output?
EDIT1
I tried to use node-pty and pty.js. They can get the ... output but they mix the input and output data together. It is not possible to separate them.
I also tried to use stdbuf and unbuffer to disable buffer but it still doesn't work.
It seems that nodejs child_process doesn't work well with interactive command.
Your code doesn't include anything that writes to the stdin of your child process so I would be surprised if you got the ellipsis that indicates incomplete command when in fact you don't send any command at all - incomplete or otherwise.
That having been said, many command line utilities behave differently when they discover a real terminal connected to their stdin/stdout. E.g. git log will page the results when you run it directly but not when you pipe the results to some other command like git log | cat so this may also be the case here.
This can also have to do with the buffering - if your stream is line-buffered then you won't see any line that is not ended with a newline right away.
The real question is: do you see the > prompt? Do you send any command to the mongo shell?
Scritping interactive CLI tools can be tricky. E.g. see what I had to do to test a very simple interactive program here:
https://github.com/rsp/rsp-pjc-c01/blob/master/test-z05.sh#L8-L16
I had to create two named pipes, make sure that stdin, stderr and stdout are not buffered, and then use some other tricks to make it work. It is a shell script but it's just to show you an example.

How do I set up a preload file for node?

Is there a way to preload some file before each time I run node (interactively), just like .vimrc, .bash_profile, etc.?
I use node mainly interactively, and I use the module CSV a lot, is there a way to avoid typing require('./csv') every time I start node?
Create an initialization file (for example ~/.noderc):
var csv = require('csv');
// put a blank line at the end of the file
Now add this line to your shell config (.bashrc / .zshrc / whatever shell you use):
alias nodei="cat ~/.noderc - | node -i"
VoilĂ !
#Ilan Frumer provided one way to do it. I think I'll give another choice here: build a REPL of your own.
From their documentation. You can find a way to write a repl of your own. You can add whatever scripts before and after the interations of it, and even use some advance API's.
For example, I created a file called .noderc.js under ~ as follows
repl = require('repl');
myFunc = function(){
console.log("Hello, there!");
};
repl.start("> ");
And you can go ahead and alias nodei="node ~/.noderc.js",
$ nodei
> myFunc()
Hello, there!
undefined

Resources