Why is my function running twice in command line but not in vscode - node.js

I am using a function from one file, in another file, and calling it there. This is causing the function to run twice at the same time when run from the command line, but not when I run it in VSCode.
Here is an example:
// fileOne
async function task() {
console.log('Hello')
}
module.exports = { task }
// fileTwo
const fileOne = require('./fileOne');
fileOne.task();
Output when ran in VSCode:
Hello
Output when ran in Command Line:
Hello
Hello
I'm not sure why this is happening... No I am not calling it in fileOne by accident because then it would also run twice in VSCode.
Thanks.

If your fileOne and fileTwo look exactly as in your problem statement, i.e.:
fileOne.js:
async function task() {
console.log('Hello')
}
module.exports = { task }
fileTwo.js:
const fileOne = require('./fileOne');
fileOne.task();
the output is 1 single 'Hello' when run in the following ways:
in Command Prompt
node fileTwo.js
in Windows PowerShell
node .\fileTwo.js
in Linux Bash Terminal
$ nodejs fileTwo.js
The same applies if you run the script having both files within 1 file (as you mention in the comments).
There were some cases where Node.js would print the output twice, but those were different scenarios.
You can try running just the fileTwo.js separately, but as already mentioned, it worked well also under a common file (e.g. your my_program_here.js in case it is just a combination of fileOne.js and fileTwo.js).

const fileOne = require('./fileOne');
This is based on the './' in different command lines.

Related

return a string from an async nodejs function called in bash

i'm calling an async nodejs function that uses prompts(https://www.npmjs.com/package/prompts)
basically, the user is presented options and after they select one, i want the selection outputted to a variable in bash. I cannot get this to work. it either hangs, or outputs everything since prompts is a user interface that uses stdout
//nodefunc.js
async run() {
await blahhhh;
return result; // text string
}
console.log(run());
// bash
x=$(node nodefunc.js)
echo $x
Unless you can ensure nothing else in the node script will print to stdout, you will need a different approach.
I'd suggest having the node script write to a temporary file, and have the bash script read the output from there.
Something like this perhaps:
const fs = require('fs');
const outputString = 'I am output';
fs.writeFileSync('/tmp/node_output.txt', outputString);
node nodefunc.js
# Assuming the node script ran succesfully, read the output file
x=$(</tmp/node_output.txt)
echo "$x"
# Optionally, cleanup the tmp file
rm /tmp/node_output.txt

Using script + screen through child_process

Solved:
I had to add \r\n at program.stdin.write(data) (something like this program.stdin.write(data+'\r\n')) and it worked.
It seems that if i don't put \r\n, it doesn't triggers, its like typing in a line without pressing enter so it will never be processed.
===========================================================================
I need to access screen through child_process, but it doesn't works properly.
First I tried to access using spawn.
const {spawn} = require('child_process');
const program = spawn('screen',['-x User/Aplication']);
program.stdout.on('data',data=>{
//Something
})
function writeTo(data){
program.stdin.write(data);
}
But i got the error "Must be connected to a terminal error". After some research i found a solution, use script+spawn to make a pseudo-console.
const {spawn} = require('child_process');
const program = spawn('script',['/dev/null']);//Pseudo-console
program.stdin.write('screen -x User/Aplication');//I access to screen through the pseudo-console, and it works.
program.stdout.on('data',data=>{
//Something
})
function writeTo(data){
program.stdin.write(data);
}
But... when I try to use writeTo, it doesn't works.
writeTo('Some command here')//Does nothing.
And somehow, when I pipe my console input, it works!
process.stdin.pipe(program.stdin);
Then I type something in my console and it proxies properly to connected screen.
Issue: It doesn't proxies properly when using program.stdin.write, but somehow, it works when i pipe my console process.stdin.pipe(program.stdin)
Observation 1: I made a short echo-program and it worked with both program.stdin.write and process.stdin.pipe(program.stdin)
echo.js
process.stdin.on('data',data=>{
console.log(`[Input]${data}`);
})
main.js
const {spawn} = require('child_process');
const program = spawn('node',['echo.js']);
program.stdout.pipe(process.stdout);
function writeTo(data){
program.stdin.write(data);
}
writeTo('Test');//Output: [Input]Test
process.stdin.pipe(program.stdin);//I type 'something'. Output: [Input]something
Observation 2: When using script+screen and piping my console, program.stdin.write only 'buffers' and process.stdin.pipe loads that buffer and sends it with what i typed.
program.stdin.write('He');//screen receives nothing
program.stdin.write('llo');//screen receives nothing
process.stdin.pipe(program.stdin);//I type ' world!'. screen receives 'Hello world!'
it may not be the whole problem, but the second argument to spawn should have each argument in a separate array element.
const program = spawn('screen',['-x', 'User/Aplication']);
I had to add \r\n at program.stdin.write(data) (something like this program.stdin.write(data+'\r\n')) and it worked.
It seems that if i don't put \r\n, it doesn't triggers as a new line and it doesn't sends it, its like typing all commands in a line without pressing enter so it will never be processed.

how to run node shelljs in sync mode and get stdout and stderr

Within a nodejs script I have the following code which makes the call synchronously and returns the stdout from the shell script I am calling:
var sh = require('shelljs');
... some code
var output = sh.exec('./someshellscript.sh', {silent:true}).stdout;
console.log(output);
... some more code (that shouldnt run until the script is complete)
I can also run the following script which will instead return the stderr:
var sh = require('shelljs');
... some code
var output = sh.exec('./someshellscript.sh', {silent:true}).stderr;
console.log(output);
... some more code (that shouldnt run until the script is complete)
However I want to receive both stdout and stderr in a sync call. Its probably something pretty obvious I am missing herebut I cant work it out.
I think you used to be able run the following command in previous versions but this just returns undefined now:
var sh = require('shelljs');
... some code
var output = sh.exec('./someshellscript.sh', {silent:true}).output;
console.log(output);
... some more code (that shouldnt run until the script is complete)
Relevant software versions are:
Ubuntu: 14.04.3 LTS
node: 4.4.4
npm: 2.15.1
shelljs: 0.7.0
Any help appreciated thanks.
From the README for the method exec(command [, options] [, callback])
Executes the given command synchronously, unless otherwise specified. [...], returns an object of the form { code:..., stdout:... , stderr:... }).
Therefore
const { stdout, stderr, code } = sh.exec('./someshellscript.sh', { silent: true })

How to send commands from a BAT file to running NodeJS process in windows?

Is it possible to make/use custom text commands in a batch file while running a nodejs server through it?
//Current batch file
node nodeServer.js
//nodeServer.js
function list(){
//insert query
}
function unlist(){
//delete query
}
As of now, after i start the batch file, the nodeServer.js is started and the batch stops accepting any input.
I'd like to be able to type "nodeServer.js list"(in the batch window) and with that, call a function called "list" inside nodeServer.js,
I'm looking to insert data about the server into a database by running a insert query with the "list" function and run a delete query with nodeServer.js unlist to remove the inserted row before shutting down the server again.
I'm unfamiliar with batch files, Is this possible?
Update
To Clarify..
I want to type a text command IN the batch window, AFTER it have started the nodejs server, to run a specific function found inside the nodeServer.js
You want to send command to the NodeJS after the node process started.
To start a command form NodeJS without pause the bat file use start
To send the command I will use a simple text file. I will write to the file from the batch using echo and read the file form NodeJS using watch, and readFileSync
I will support sending function name and arguments using spaces. for example: list a b c
The BAT file:
#echo off This is make the bat file to not show the commands
REM `Rem` do nothing. It is exactly like // in javascript
REM This will start NodeJS without pause the bat
start node myNode.js
REM delete the command file if it exists
del command
REM Send 3 commands to the file. You can also add parameters
echo list >> command
echo list a b c>> command
echo unlist>> command
var fs = require('fs')
var filename = __dirname + '/command'
// Add here any command you want to be run by the BAT file
var commands = {
list: function() {
console.log('list', arguments)
},
unlist: function() {
console.log('unlist', arguments)
}
}
console.log('watching:' + filename)
if (fs.existsSync(filename)) {
console.log('File exists, running initial command')
runCommand()
}
require('fs').watchFile(filename, runCommand)
function runCommand() {
if(!fs.existsSync(filename)) return
var lines = fs.readFileSync(filename, 'utf-8').split('\r\n')
console.log(lines)
fs.unlink(filename)
for(var i=0;i<lines.length;i++){
var line=lines[i]
console.log(line)
line=line.split(' ') // Split to command and arguments
var command = line[0]
var args = line.slice(1)
if (!commands[command]) {
console.log('Command not found:"' + command +'"')
return;
}
console.log('Running command:', command, '(', args, ')')
commands[command].call(null, args)
}
}
Read more about FileSystem node Module: https://nodejs.org/docs/latest/api/fs.html#fs_class_fs_stats

running node app with exports.object from command line and lambda

I am still in the process of learning node and have come across this issue. In the following situation, and using a silly example (the full code can not be placed here), when I run in the terminal node index.js somethinghere, the code does not execute. I realise that event and context have no bearing in this example, but they do in the code I am currently writing.
Is this because I am doing exports.imageRs?
How would I get it to run on the command line by passing in arguments?
Note that the original code is to be run on both aws lambda and from the command line.
file index.js
exports.imageRs = function (event, context) {
console.log(process.argv);
}
In the example you have shown Node will define exports.imageRs function but it won't execute it.
The fix is something along these lines:
exports.imageRs = function (event, context) {
console.log(process.argv);
};
if (!module.parent) {
exports.imageRs();
}
!module.parent check prevents the code inside from executing when your module is required from other modules, which is probably what you want.
$ node index.js somethinghere
[ '/path/to/node',
'/path/to/index.js',
'somethinghere' ]
$ node
> require('./index')
{ imageRs: [Function] }

Resources