My goal is to be able to execute a command on a remote machine and get the full stdout response from the command that was run. What I am getting is a truncated result. When I run the same command through command prompt, I get the full output from the command run. Here is my code:
var process = spawn('PsExec.exe', ['\\\\servername', 'ipconfig']);
var doOnce = true;
process.stdout.on('data', function (data) {
log.info('stdout: ' + data.toString());
if(doOnce){
doOnce = false;
process.stdin.write('ipconfig');}
});
process.stderr.on('data', function (data) {
log.info('stderr: ' + data.toString());
});
process.on('exit', function (code) {
log.info('child process exited with code ' + code);
});
When executed I get the following console output. As you can tell, all of ipconfig has been truncated. If I do another command such as netstat, I get most of the results before truncating occurs, so I don't believe this has anything to do with the buffer. I really am just out of ideas at this point.
info: stderr:
PsExec v2.11 - Execute processes remotely
Copyright (C) 2001-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
info: stdout:
Windows IP Configuration
ipconfig exited on servername with error code 0.
info: child process exited with code 0
Try using the { stdio: 'inherit' } option
var spawn = require('child_process').spawn,
appname = spawn('psexec.exe', ['-accepteula', '\\\\remotepcname', '-u', 'domain\\username', '-p', 'supersecretpassword', 'ipconfig'], { stdio: 'inherit' });
Related
Okay, so I have an API written in Nodejs that is clustered to make use of all the cores available using the 'cluster' module for a total of 4 child processes.
const cluster = require('cluster');
I have a process ('remNodeProcess') which I need to fork only 1 instance of, i.e I don't want each worker node forking its own instance of 'remNodeProcess'. This 'remNodeProcess' does NOT need to be available to every child node. For this I'm trying to use the 'child-process' module.
const childProcess = require('child_process');
I've had a good read of Node Clusters and have been using them for a short while. Clustering is working as expected and I'm getting the desired results but I can't seem to figure out how to fork a single instance of a process. I only want 1 instance of this process in the cluster.
Here's the full code to cluster:
const setupWorkerThreadNodes = () => {
// Get system CPUs
let SYS_CORE_COUNT = require('os').cpus().length;
// Read the Config Thread Configuration, if it exceeds the SYS_CORE_COUNT, set it to max usage, otherwise honour the Config
let coreCount;
if (webAppConfig.appConfig.nodeClusterConfiguration.mtMaxWorkerThreadCount) {
coreCount = webAppConfig.appConfig.nodeClusterConfiguration.mtMaxWorkerThreadCount;
} else if (webAppConfig.appConfig.nodeClusterConfiguration.mtMaxWorkerThreadCount > SYS_CORE_COUNT) {
coreCount = SYS_CORE_COUNT;
}
logMsg(`NODE_MASTER PID: ${process.pid}`);
console.log('NODE_CLUSTER Master is setting up Nodes... ');
// For each Core, create a node and push it to the system cluster array
for (let i = 0; i < coreCount; i++) {
console.log(`NODE_CLUSTER Master is setting up Node [${i}/${coreCount}]... `);
workers.push(cluster.fork({ WorkerName: `Worker${i}` }));
// When a Worker responds to the Master, log the response
workers[i].on('message', function (message) {
console.log(message);
});
}
// process is clustered on a core and process id is assigned
cluster.on('online', function (worker) {
console.log('Worker ' + worker.process.pid + ' is listening');
logMsg(`CLUSTER_NODE Child opened. PID: ${worker.process.pid}`)
});
// If the Workers count matches the CoreCount, we've opened the correct amount of threads
if (workers.length === coreCount) logMsg(`NODE_CLUSTER Array successfully established.`, 'info');
// if any of the worker process dies then start a new one by simply forking another one
cluster.on('exit', function (worker, code, signal) {
console.log('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
logMsg(`CLUSTER_NODE Child terminated. PID: ${worker.process.pid}. Code: ${code}. Signal: ${signal}`)
console.log('Starting a new worker');
cluster.fork();
workers.push(cluster.fork());
// to receive messages from worker process
workers[workers.length - 1].on('message', function (message) {
console.log(message);
});
});
};
I've tried the following:
if(cluster.isMaster){
const remNodeProcess= childProcess.fork('./background_workers/remNode.js');
remNodeProcess.send(pool, (err) => { console.log(err) })
}
When I run the API with this code, remNodeProcess does not open. If I use the following code (without the IF wrapper):
const remNodeProcess= childProcess.fork('./background_workers/remNode.js');
remNodeProcess.send(pool, (err) => { console.log(err) })
I get one remNodeProcess for every child.
How do I fork one instance of a given process? and can this be done from the Master?
I've figured it out.
This will manually fork the Reminder child if the current worker has a WorkerName of Worker0. The result is only 1 instance of the remNode in the cluster and not 4.
if (process.env.WorkerName === "Worker0") {
console.log(`${process.env.WorkerName} forking ReminderNode...`)
remNodeProcess = childProcess.fork('./background_workers/remNode.js')
.on('message', msg => {
logMsg(msg)
});
}
I am trying to run a .bat file by passing arguments to it in nodejs. However, I get an empty command prompt. How to get the command pasted on the path.
code -
server.js
var bat = require.resolve('E:/API_Gateway_through_Swagger/New_Project/aws-bat-file-3.bat');
var num = "123"
var state_desc = "abc";
var ls = spawn(bat, [num, state_desc ]);
ls.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
ls.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
ls.on('exit', function (code) {
console.log('child process exited with code ' + code);
});
Bat file -
aws-bat-file-3.bat
echo off
echo "Batch Started"
set arg1=%1
set arg2=%2
START "Task Options" cmd.exe /b " cd C:\Users\myfolder & aws apigateway create deployment --rest-api-id %arg1% --stage-name dev --stage-description %arg2%"
output img file is -
NodeJS documented the problem of spawning batch files on Windows thoroughly in this section.
Excerpt:
When running on Windows, .bat and .cmd files can be invoked using child_process.spawn() with the shell option set, with child_process.exec(), or by spawning cmd.exe and passing the .bat or .cmd file as an argument (which is what the shell option and child_process.exec() do).
const bat = spawn('"my script.cmd"', ['a', 'b'], { shell: true });
hope you're having an awesome day.
I'm running a CasperJS scrape across around 100,000 links over the course of a few days (continuously).
For every 500 or so, casperJS crashes randomly. When reloaded and started from the last link, however, it continues for another 500.
I was wondering if someone knows of an effective way I might be able to refresh or close & reinstance casperjs, to avoid this burnout? I was thinking of an exit() paired with a wait, but very keen on thoughts!
The script is similar to:
var casper = require('casper').create({
verbose: true,
logLevel: 'error',
pageSettings: {
loadImages: false,
loadPlugins: true,
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11'
},
clientScripts: ['vendor/jquery.min.js', 'vendor/lodash.js'],
viewportSize: {
width: 1600,
height:1000
}
});
var linkArray = [ // Includes 100,000 + links ]
function inspectUrl(url) {
casper.thenOpen(url, function() {
title = this.getPageTitle();
bodyText = this.fetchText('body');
// Includes a bunch of other tasks to do.
}
casper.start('https://www.google.com.au', function() {
console.log('Booting up CasperJS...');
});
casper.then(function() {
for (var i = 0; i < linkArray.length; i++) {
inspectUrl(linkArray[i]);
};
});
casper.run()
There is a known PhantomJS memory problem. You should develop a "runner", which runs your CasperJS script with some 400 links, collects result, then runs another instance of the script with another portion of links and so far.
Maybe you can make some CasperJS instances run in parallel, if you need speed.
You can develop such a runner with PhantomJS, using the spawn function.
The function is described briefly in the PhantomJS docs: http://phantomjs.org/api/child_process/
UPDATE:
You can find below a working example of such a runner. The example is very simple, just to demonstrate how one could spawn CasperJS instances and collect their results. In particular, there is no error handling in the example at all. The example have been tested with PhantomJS 2.1.1.
The runner uses Q promises, so first you have to make file package.json with the following content:
{
"dependencies": {
"q": "1.4.1"
}
}
and run installer:
npm install
Then you have to create runner.js:
var Q = require('q');
var childProcess = require('child_process');
var parserTasks = [
'http://phantomjs.org/',
'http://casperjs.org/',
'https://jquery.com/'
];
run(parserTasks).then(function(result) {
console.log('Tasks result: ' + JSON.stringify(result));
phantom.exit();
});
function run(tasks) {
if (tasks.length) {
var task = tasks.pop();
return runTask(task).then(function(result) {
console.log('result: ' + result);
return run(tasks).then(function(results) {
return([result].concat(results));
});
});
} else {
return Q([]);
}
}
function runTask(task) {
var defer = Q.defer();
var spawn = childProcess.spawn;
var result = '';
var child = spawn('casperjs', ['parser.js', task]);
console.log("spawn run: " + task);
child.stdout.on("data", function(data) {
result += data;
});
child.on("exit", function() {
defer.resolve(result);
});
return defer.promise;
}
and parser.js
var casper = require('casper').create();
var url = casper.cli.args[0];
var result;
casper.start();
casper.thenOpen(url, function() {
result = this.getTitle();
});
casper.run(function() {
this.echo(result).exit();
});
You could execute the runner the following way, meaning that phantomjs executable is somewhere on PATH.
phantomjs runner.js
The output should be the following:
spawn run: https://jquery.com/
result: jQuery
spawn run: http://casperjs.org/
result: CasperJS, a navigation scripting and testing utility for PhantomJS and SlimerJS
spawn run: http://phantomjs.org/
result: PhantomJS | PhantomJS
Tasks result: ["jQuery\n","CasperJS, a navigation scripting and testing utility for PhantomJS and SlimerJS\n","PhantomJS | PhantomJS\n"]
I have tried different configuration, but I cannot seem to succeed to execute "gs" (Ghostscript) in a node.js environment.
var fs = require( "fs" ),
child_process = require( 'child_process' );
...
var spawn = child_process.spawn;
var opts = [
"-q ",
"-dQUIET ",
"-dSAFER ",
"-dBATCH ",
"-dNOPAUSE ",
"-dNOPROMPT ",
"-dMaxBitmap=500000000 ",
"-dAlignToPixels=0 ",
"-dGridFitTT=2 ",
"-sDEVICE=jpeg ",
"-dTextAlphaBits=4 ",
"-dGraphicsAlphaBits=4 ",
"-r150 ",
"-sOutputFile=afile.jpg",
" afile.pdf"
];
var gs = spawn( "gs", opts, { cwd: "/mnt/drive/" } );
gs.stdout.on( 'data', function( data ) {
console.log( 'stdout: ' + data );
} );
gs.stderr.on( 'data', function( data ) {
console.log( 'stderr: ' + data );
} );
gs.on( 'close', function( code ) {
console.log( 'child process exited with code ' + code );
} );
---Output ---------------------------------------------------------
stdout: Unknown device: jpeg
stdout: Unrecoverable error: undefined
stdout: in .uninstallpagedevice
stdout: Operand stack:
defaultdevice
stdout:
child process exited with code 1
-------------------------------------------------------------------
The /mnt/drive directory is +read+write for all users. The gs -help execution returns:
root#Machine:/# gs -help
GPL Ghostscript 9.05 (2012-02-08)
Copyright (C) 2010 Artifex Software, Inc. All rights reserved.
Usage: gs [switches] [file1.ps file2.ps ...]
Most frequently used switches: (you can use # in place of =)
-dNOPAUSE no pause after page | -q `quiet', fewer messages
-g<width>x<height> page size in pixels | -r<res> pixels/inch resolution
-sDEVICE=<devname> select device | -dBATCH exit after last file
-sOutputFile=<file> select output file: - for stdout, |command for pipe,
embed %d or %ld for page #
Input formats: PostScript PostScriptLevel1 PostScriptLevel2 PostScriptLevel3 PDF
Default output device: bbox
Available devices:
...
ijs imagen inferno inkcov iwhi iwlo iwlq jetp3852 jj100 jpeg jpegcmyk
jpeggray la50 la70 la75 la75plus laserjet lbp310 lbp320 lbp8 lex2050
...
txtwrite uniprint xcf xes
Search path:
/usr/share/ghostscript/9.05/Resource/Init :
/usr/share/ghostscript/9.05/lib :
/usr/share/ghostscript/9.05/Resource/Font :
/usr/share/ghostscript/fonts : /var/lib/ghostscript/fonts :
/usr/share/cups/fonts : /usr/share/ghostscript/fonts :
/usr/local/lib/ghostscript/fonts : /usr/share/fonts
For more information, see /usr/share/doc/ghostscript/Use.htm.
Please report bugs to bugs.ghostscript.com.
root#Machine:/#
Where the device jpeg is available. The gs execution is not perform. Any hint would be help ?
The only way I got it to work, is by upgrading node from 10.26 to the latest 10.32, AND encapsulate the gs execution in a simple bash script file. Otherwise, even with the 10.32 node version, I still get the same error. I suspected an environment problem like suggest #Rudie,
You could consider to use Ghostscript4JS, it's a module that binds the Ghostscript C command API to bring its power to the Node.JS world.
https://www.npmjs.com/package/ghostscript4js
Ghostscript4JS is a native Node.JS addon so you can call the C command Ghostscript API directly from your JavaScript code. In this way you have two benefits:
Better error handling:
You directly intercept the error through the try/catch for the sync method and then/catch promise for the async method.
Performance
The call to the shell command takes more time and more resources than the call to the C or C++ API directly from Node.js environment.
As programmer you have more control against call external tool.
You just need to remove the spaces in the list of options
I have a nodejs file runner.node.js.
If I run node runner.node.js it works
But if I try tu run it with npm test (it's referenced in package.json):
"test": "node ./spec/runner.node.js"
or
"test": "spec/runner.node.js"
It says that the file isn't executable:
sh: 1: spec/runner.node.js: Permission denied
npm ERR! Test failed. See above for more details.
npm ERR! not ok code 0
If I set the file as executable it then says:
spec/runner.node.js: 1: spec/runner.node.js: Syntax error: word unexpected (expecting ")")
npm ERR! Test failed. See above for more details.
npm ERR! not ok code 0
while it still runs correctly with "node spec/runner.node.js"
The file is this:
console.log("Running Knockout tests in Node.js");
var fs = require('fs');
var jasmine = require('./lib/jasmine-1.2.0/jasmine');
// export jasmine globals
for (var key in jasmine) {
global[key] = jasmine[key];
}
// add our jasmine extensions to the exported globals
require('./lib/jasmine.extensions');
// export ko globals
if (process.argv.length > 2 && process.argv[2] == '--source') {
// equivalent of ../build/knockout-raw.js
global.DEBUG = true;
global.ko = global.koExports = {};
global.knockoutDebugCallback = function(sources) {
sources.unshift('build/fragments/extern-pre.js');
sources.push('build/fragments/extern-post.js');
eval(sources.reduce(function(all, source) {
return all + '\n' + fs.readFileSync(source);
}, ''));
};
require('../build/fragments/source-references');
} else {
global.ko = require('../build/output/knockout-latest.js');
}
// reference behaviors that should work out of browser
require('./arrayEditDetectionBehaviors');
require('./asyncBehaviors');
require('./dependentObservableBehaviors');
require('./expressionRewritingBehaviors');
require('./extenderBehaviors');
require('./mappingHelperBehaviors');
require('./observableArrayBehaviors');
require('./observableBehaviors');
require('./subscribableBehaviors');
// get reference to jasmine runtime
var env = jasmine.jasmine.getEnv();
// create reporter to return results
function failureFilter(item) {
return !item.passed();
}
env.addReporter({
reportRunnerResults:function (runner) {
var results = runner.results();
runner.suites().map(function (suite) {
// hack around suite results not having a description
var suiteResults = suite.results();
suiteResults.description = suite.description;
return suiteResults;
}).filter(failureFilter).forEach(function (suite) {
console.error(suite.description);
suite.getItems().filter(failureFilter).forEach(function (spec) {
console.error('\t' + spec.description);
spec.getItems().filter(failureFilter).forEach(function (expectation) {
console.error('\t\t' + expectation.message);
});
});
});
console.log("Total:" + results.totalCount + " Passed:" + results.passedCount + " Failed:" + results.failedCount);
process.exit(results.failedCount);
}
});
// good to go
env.execute();
Add
#/usr/bin/env node
as the first line in your file. This way, when run as an executable your OS will know that it shall use Node.js to run it (to be exactly: your OS will know that it shall use the first application called node to execute your script).