Meteor interaction with the command line?


#1

For my current project, I need to use API calls to make command line calls. For example, I need to get the ipconfig of the machine running the server when I make a GET call, and get the result as a response from the page.

Execution of the command was easy, but I am getting issues getting the information back to the caller.

Here is what I have right now:

if(Meteor.isServer){

	//HTTP calls made to /newReport/
	Router.route('/api/ipconfig/', {where: 'server'})

	//When a GET call is made
	.get(function(){

		console.log("Got to GET");

		comRes = command('ipconfig');

		if(!comRes)
			console.log("[.] Return is empty")

		respondWithJson(201, this.response, comRes);
	});


var command = function(com){

	// We need this to have the console.
	execute = Npm.require('child_process').exec;

	//Where the response will be
	var response;

	//shell: 'cmd.exe' to use Windows command line. Default is Unix shell.
	child = execute(com, {shell: 'cmd.exe'}, function(error, stdout, stderr) {

		response = {
			stdout: stdout,
			stderr: stderr
		};

		if(error !== null) {
			console.log('exec error: ' + error);
		}
	});

	return response;
}

As you can see, the actual connection to the command line is done in the function command(com)

If I write down some console.log() commands to track the progress, I can see that stdout and stderr are not empty inside the command(com) function, therefore when I return response, it should not be empty. However, when I get to the check to see if comRes is empty, I get that it is indeed null.

I’m assuming that Meteor is separating tasks, and therefore finishing the rest of the GET call before finishing the command(com) function call.

Any ideas? Is this the best way to make cmd statements? How can I return sdtout to the GET caller?

Thank you!


#2

Look up Meteor.wrapAsync in the Meteor docs and on google or the lower-level, but fundamentally equivalent way of using Fibers and Futures directly.
Your problem is that the child_process.exec call is asynchronous, but the response value you’re returning is being done synchronously, i.e. before the actual exec even happens. But there is a way to make Meteor wait and that’s what that stuff in the first paragraph does!