How to execute the command NPM init in the nodejs file - node.js

How to execute the command npm init in the nodejs file? I want to use node. / index.js to execute the command. But what should I do if the command interacts with the user?
This code is directly stuck, and the subsequent question and answer cannot be carried out.I hope users can fill in the information normally
let exec = require('child_process').exec;
exec("npm init")

To allow users to fill in the questionnaire via the CLI, consider using the child_process module's spawn() method instead of exec().
*Nix (Linux, macOS, ... )
For example:
index.js
const spawn = require('child_process').spawn;
spawn('npm', ['init'], {
shell: true,
stdio: 'inherit'
});
Note: After the user has completed the questionnaire this example (above) creates the resultant package.json file in the current working directory, i.e. the same directory from where the node command invoked index.js.
However, If you want to ensure that package.json is always created in the same directory as where index.js resides then set the value of the cwd option to __dirname. For example:
const spawn = require('child_process').spawn;
spawn('npm', ['init'], {
cwd: __dirname, // <---
shell: true,
stdio: 'inherit'
});
Windows
If you are running node.js on Windows then you need to use the following variation instead:
script.js
const spawn = require('child_process').spawn;
spawn('cmd', ['/c', 'npm init'], { //<----
shell: true,
stdio: 'inherit'
});
This also utilizes the spawn() method, however it starts a new instance of Windows command shell (cmd). The /c option runs the npm init command and then terminates.
Cross-platform (Linux, macOS, Windows, ... )
For a cross platform solution, (i.e. one that runs on Windows, Linux, macOS), then consider combining the previous examples to produce the following variation:
script.js
const spawn = require('child_process').spawn;
const isWindows = process.platform === 'win32';
const cmd = isWindows ? 'cmd' : 'npm';
const args = isWindows ? ['/c', 'npm init'] : ['init'];
spawn(cmd, args, {
shell: true,
stdio: 'inherit'
});

Assuming there doesn't need to be any user input you could do:
let exec = require('child_process').exec;
exec("npm init -y")

Related

Node child_process pass argv when forked

I have Node application with Express server. I also have node scripts in server folder. During some events I need get data from separate node scripts, so I create child process.
Without arguments, everything works fine, but I need to pass some data from parent process.
var express = require('express');
var router = express.Router();
var child_process = require('child_process');
router.get('/:site/start', function(req, res, next) {
const basedir = req.app.get('basedir');
const child_script_path = basedir + '/scripts/script.js';
const child_argv = [
'--slowmo=0',
'--headless=1'
];
child = child_process.fork(child_script_path, {
execArgv: child_argv
});
...
}
});
When I try to pass arguments and run script through Express, these errors are shown:
/home/user/.nvm/versions/node/v8.9.4/bin/node: bad option: --slowmo=0
/home/user/.nvm/versions/node/v8.9.4/bin/node: bad option: --headless=1
But when I run script from command line like :
node /scripts/script.js --slowmo=0 --headless=1
I get no errors and script can catch args from command line.
How can I pass args to child script in this situation?
Ubuntu 16.04
Node 8.9.4
Express 4.15.5
execArgv option is used to pass arguments for the execution process, not for your script.
This could be useful for passing specific execution environment to your forked process.
If you want to pass arguments to your script, you should use args.
child_process.fork(modulePath[, args][, options])
Example:
const child_process = require('child_process');
const child_script_path = './script.js';
const child_argv = [
'--foo',
'--bar'
]
const child_execArgv = [
'--use-strict'
]
let child = child_process.fork(child_script_path, child_argv, {
execArgv: child_execArgv // script.js will be executed in strict mode
})
// script.js
console.log(process.argv[2], process.argv[3]) // --foo --bar

Error: spawn ENOENT on Windows

I'm on node v4.4.0 and on Windows 10. I'm using bunyan to log my node application.
try {
var fs = require('fs');
var path = require('path');
var spawn = require('child_process').spawn;
var through = require('through');
} catch (err) {
throw err;
}
var prettyStream = function () {
// get the binary directory of bunyan
var bin = path.resolve(path.dirname(require.resolve('bunyan')), '..', 'bin', 'bunyan');
console.log(bin); // this outputs C:\www\nodeapp\src\node_modules\bunyan\bin\bunyan, the file does exist
var stream = through(function write(data) {
this.queue(data);
}, function end() {
this.queue(null);
});
// check if bin var is not empty and that the directory exists
if (bin && fs.existsSync(bin)) {
var formatter = spawn(bin, ['-o', 'short'], {
stdio: [null, process.stdout, process.stderr]
});
// stream.pipe(formatter.stdin); // <- did this to debug
}
stream.pipe(process.stdout); // <- did this to debug
return stream;
}
The logging spits out in the console due to the fact I used stream.pipe(process.stdout);, i did this to debug the rest of the function.
I however receive the error:
Error: spawn C:\www\nodeapp\src\node_modules\bunyan\bin\bunyan ENOENT
at exports._errnoException (util.js:870:11)
at Process.ChildProcess._handle.onexit (internal/child_process.js:178:32)
at onErrorNT (internal/child_process.js:344:16)
at nextTickCallbackWith2Args (node.js:442:9)
at process._tickCallback (node.js:356:17)
at Function.Module.runMain (module.js:443:11)
at startup (node.js:139:18)
at node.js:968:3
I'm guessing this is a Windows error. Anyone have any ideas?
Use {shell: true} in the options of spawn
I was hit with this problem recently so decided to add my findings here. I finally found the simplest solution in the Node.js documentation. It explains that:
child_process.exec() runs with shell
child_process.execFile() runs without shell
child_process.spawn() runs without shell (by default)
This is actually why the exec and spawn behave differently. So to get all the shell commands and any executable files available in spawn, like in your regular shell, it's enough to run:
const { spawn } = require('child_process')
const myChildProc = spawn('my-command', ['my', 'args'], {shell: true})
or to have a universal statement for different operating systems you can use
const myChildProc = spawn('my-command', ['my', 'args'], {shell: process.platform == 'win32'})
Side notes:
It migh make sense to use such a universal statement even if one primairly uses a non-Windows system in order to achieve full interoperability
For full consistence of the Node.js child_process commands it would be helpful to have spawn (with shell) and spawnFile (without shell) to reflect exec and execFile and avoid this kind of confusions.
I got it. On Windows bunyan isn't recognized in the console as a program but as a command. So to invoke it the use of cmd was needed. I also had to install bunyan globally so that the console could access it.
if (!/^win/.test(process.platform)) { // linux
var sp = spawn('bunyan', ['-o', 'short'], {
stdio: [null, process.stdout, process.stderr]
});
} else { // windows
var sp = spawn('cmd', ['/s', '/c', 'bunyan', '-o', 'short'], {
stdio: [null, process.stdout, process.stderr]
});
}
I solved same problem using cross-spawn. It allows me to spawn command on both windows and mac os as one common command.
I think you'll find that it simply can't find 'bunyun', but if you appended '.exe' it would work. Without using the shell, it is looking for an exact filename match to run the file itself.
When you use the shell option, it goes through matching executable extensions and finds a match that way. So, you can save some overhead by just appended the executable extension of your binary.
I was having this same problem when trying to execute a program in the current working directory in Windows. I solved it by passing the options { shell: true, cwd: __dirname } in the spawn() call. Then everything worked, with every argument passed as an array (not attached to the program name being run).
I think, the path of bin or something could be wrong. ENOENT = [E]rror [NO] [ENT]ry

Spawning child_process in NodeJS with valid HOME folder set

I'm trying to spawn a process in NodeJS that accesses the my home folder, and can't see, to get either of the options below to work.
var spawn = require('child_process').spawn,
options = {stdio: 'inherit', env: process.env};
spawn('ls', ['~/'], options);
spawn('ls', ['$HOME'], options);
Output
ls: ~/: No such file or directory
ls: $HOME: No such file or directory
I've verified that options.env.HOME is properly set, any idea what I'm doing wrong?
Update
So this is what I ended up doing to make my use-case work (using script instead of ls):
spawn('script', [process.env.HOME], options);
Then, inside of my script:
#!/usr/bin/env bash
export HOME=$1
I still don't understand why options.env.HOME does not seem to work as expected.
process.env.HOME is what you want. Use it like so:
var spawn = require('child_process').spawn,
options = {stdio: 'inherit'};
var ls = spawn('ls', [process.env.HOME]);
ls.stdout.on('data', function(data){
console.log(String(data));
});
ls.stderr.on('data', function(data){
console.log(String(data));
});
Then you can set HOME in your shell when invoking the node script:
HOME='/tmp'; node ls.js
Alternatively, you don't have to overload HOME. To use whatever variable you like export it first, and then access it through process.env.:
export FOO='/tmp'; node ls.js

How can I redirect a jsnode child process output to a cmd prompt?

I have an appjs application that is built to be a GUI which allows the user to run whole bunch of other .exe applications. These other .exe applications are created on a mouse click by the 'spawn()' command. Some of the .exe programs require output on the command line, however the main application doesn't use a command prompt.
So basically, I want my child processes to pipe their stdout into a command prompt window. The command prompt window is not running before hand. I am new to jsnode and I am having trouble getting this to work.
Here is the code. The name of the application is getting passed into the function and I am constructing the string and then spawning the process.
var appName = this.getAttribute('app');
processStr = './' + appName + '.exe';
var spawn = require('child_process').spawn;
cmd = spawn(processStr, [], { cwd: './', env: process.env} );
Note, even if I change it to below I cannot get the command prompt window to show up.
cmd = spawn('c:/windows/system32/cmd.exe', [], { cwd: './', env: process.env} );
var spawn = require('child_process').spawn;
var child = spawn('echo', ['Hello world!']);
child.stdout.pipe(process.stdout)

Spawn child_process on directory

How to spawn this command (/usr/bin/which flac) on node.js:
var spawn = require('child_process').spawn;
var cmd = spawn('/usr/bin/which flac', parameters);
I've tried that code but its not working, assuming that parameters variables are set.
In your case, flac needs to be passed as a parameter. Try this:
var spawn = require('child_process').spawn;
var cmd = spawn('/usr/bin/which', ['flac'], {detached:true, stdio: 'inherit'})
.on('exit',function(code){
//check exit code
});
For example, running the same code with node instead of flac gives:
/usr/bin/node

Resources