I'm trying to pass a command line argument through node like so: npm start -s config.yml, where npm start maps to node app.js in my package.json.
app.js is as follows:
const program = require('commander');
console.log(process.argv);
program
.command('-s, --shell <value>', '.yml config file')
.parse(process.argv);
console.log(program.shell);
the argument is being passed through process.argv, but when I log program.shell it comes back undefined. What am I doing wrong?
Running the following:
$ node runme.js shell aceofspades
On the following file:
// FILE: runme.js
const program = require('commander');
program
.command('shell [value]', '.yml config file')
.action((cmd, opt) => {
console.log('cmd:', cmd); // shell
console.log('opt:', opt); // aceofspades
});
program.parse(process.argv);
Gives me the command and arguments within the action function for the command.
Related
I have this string I need to execute on MacOS shell: solana --help
It runs fine as expected in the macOS terminal, even if I cd into my project directory.
The said application is on my global PATH too.
I have the following code opened in my vscode project:
const util = require('util');
const exec = util.promisify(require('child_process').exec);
(async () => {
const { stdout, stderr } = await exec('solana --help');
console.log('stdout:', stdout);
console.log('stderr:', stderr);
})();
Instead of showing expected output, the program errors out and shows the following error:
https://i.stack.imgur.com/fseXV.png
You need to type whereis solana in the command line to find the full path to that executable, then replace that in your code, i.e:
const { stdout, stderr } = await exec('full_path_to_solana --help');
Then show us the result.
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")
I want to set/change user variable in my windows/Linux system. one of them is my APP_SOME_VAR variable.
When I run env in the command line I'm getting a list of my user variables.
When I run this code in my file.js it doesn't change my variable in the command line.
const { execSync } = require('child_process');
let output = execSync(`echo blabla && set APP_SOME_VAR=blabla`);
After I run the file, I do this in the command line:
node app.js
env | grep SOME
But I get nothing from: APP_SOME_VAR
How to do that with nodejs?
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
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 })