Can Node.js launch scripts on the server? - node.js

Can Node.js launch scripts on the server it is installed on? Scripts like bash scripts or PHP scripts, for example to resize pictures?
If so, how how is it? Can you point me to a documentation page, please?
Thanks,
Dan

Yes it is possible. The following give a demonstration:
http://www.dzone.com/snippets/execute-unix-command-nodejs
http://groups.google.com/group/nodejs/browse_thread/thread/e3d00bb0e48dd760?pli=1
You can also perform tasks such as spawning child processes, and clustering.
Executing a unix command:
var exec = require('child_process').exec;
child = exec("something", function (error, stdout, stderr) {
sys.print('stdout: ' + stdout);
sys.print('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
See Node.js Documentation for more: http://nodejs.org/api/child_process.html

Related

child_process.exec() stdout is empty string when command contains spaces

I have put the below code in a Javascript file and ran it using node.
var exec = require('child_process').exec;
var child;
child = exec("git for-each-ref --format='%(committerdate), %(authorname)' --sort=committerdate --merged develop",
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('typeof stdout: ' + typeof stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
All I get is an empty string as stdout. There are no errors.
stdout:
stderr:
However, if I remove the space after comma in "%(committerdate), %(authorname)", I get the expected output. The below code works:-
var exec = require('child_process').exec;
var child;
child = exec("git for-each-ref --format='%(committerdate),%(authorname)' --sort=committerdate --merged develop",
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
Why do I not get any output when there is a space after comma?
When I run the command directly on in PowerShell or git-bash, I get the same output with and without the space.
git for-each-ref --format='%(committerdate), %(authorname)' --sort=committerdate --merged develop
I spent quite some time to get the command working and it seemed to be that a space would cause an issue, especially when the command works fine when run directly.
Environment:
Windows 10
Node 16.7.0
It's probably worth putting into an answer to give people ideas on how to troubleshoot.
Let's look at the command first:
exec("git for-each-ref --format='%(committerdate), %(authorname)' --sort=committerdate --merged develop", ...);
If we wanted to look at the underbelly of the exec function, we would probably find a more sophisticated version of inputString.split(" ") so that node can distinguish the executable from the positional arguments/flags. So a good place to start is to try and escape the space in various ways to see if that works.
Next you need to understand how node executes the command. On different operating systems, the node child_process library is just a proxy to an underlying shell. So you need to make sure your command works in the target shell (which is likely not your favorite shell or the one you use on a day-to-day basis). For Windows, node likely uses cmd.exe under the hood.
Lastly, the child_process library also allows you to spawn a process which is a little more deliberate in specifying the executable and positional arguments/flags. I recommend using this method for most child_process operations:
spawn(<executable>, [...<args>]);
This way you are telling node exactly what binary to use while clearly identifying every positional argument. For example, the following will fail:
spawn('git', ['checkout -b my-new-branch']);
The reason this fails is because node treats the string 'checkout -b my-new-branch' as a single argument to the git command... which is not correct. Instead, you want to clearly define each positional argument separately:
spawn('git', ['checkout', '-b', 'my-new-branch']);
This is particularly useful if one of your arguments contains spaces or other special shell characters:
spawn('git', ['checkout', '--format=\'%(committerdate), %(authorname)\'', '--sort=committerdate', '--merged develop']);
Changing the underlying shell
For any of the child_process creation methods, you can pass an option for which shell to use. Be careful using this option because you can destroy the ability for your code to run on multiple operating systems. Make sure to read about shell requirements and the default windows shell:
exec("...", { shell: "powershell.exe" });
spawn("...", [...], { shell: "powershell.exe" });

nodejs command line module not giving stdout

I have set up a command line node module and when I run it one of the tasks is to start up the server and log to the console. However I find that although it starts up my server fine, it does not send the output to the console.
#! /usr/bin/env node
var userArgs = process.argv.slice(2);
var searchPattern = userArgs[0];
if(userArgs[0] === "start"){
var exec = require('child_process').exec;
exec('node ./server.js',
function(err, stdout, stderr) {
console.log('stdout: ', stdout);
console.log('stderr: ', stderr);
if (error !== null) {
console.log('exec error: ', error);
}
}
);
}
So if I npm link my module then run mymodule start it starts the server fine but as I mentioned no output to the console.
Whereas if I run simply node server.js I get the output which is server listening on http://localhost:5000.
From the documentation, regarding the callback you are passing to 'exec'
'callback' - Function called with the output when process terminates
From what I understand, the process has to be terminated before you see 'stdout:' and 'stderr:' (you would have to stop the node process).

Automatic writing text to the console using Node.js

I need to clone GitHub repository using SSH and Node.js script:
var exec = require('child_process').exec;
exec('git clone git#github.com:jquery/jquery.git',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
}
);
If github.com not in known_hosts file, SSH forcing to enter "yes" on the question "Are you sure you want to continue connecting (yes/no)?".
How can I automate the input of this text?
P.S. I know about StrictHostKeyChecking=no, but I need to clone repository without changing SSH config.
Sure, that is entirely possible. When you call child_process.exec, it actually returns a ChildProcess Object. It contains an .stdin object which is an implementation of a Writable Stream, which you can pipe to / write to. Documentation on ChildProcess.stdin, also on Writable Stream.
Here is some example code that relates to your question:
var exec = require('child_process').exec;
var cmd = exec('git clone git#github.com:jquery/jquery.git', function (error, stdout, stderr) {
// ...
});
cmd.stdin.write("yes");
You could pass in yes prior to your git clone command.
exec('yes | git clone git#github.com:jquery/jquery.git'...

CasperJS/PhatomJS running shell commands

For the last few days I have been struggling with running shell commands from CasperJS/PhantomJS.
I am running simple unix sed on a file in node, which runs just fine:
var sys = require('sys')
var exec = require('child_process').exec;
var child;
// executes `sed`
child = exec("sed -i -e '1,1000d' file.name", function (error, stdout, stderr) {
sys.print('stdout: ' + stdout);
sys.print('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
But whenever I run same with CasperJS, it just runs forever, not executing the shell command. Maybe someone could shed some light on this.
I did actually make it work through spawn and execFile functions from PhatomJS, but the issue is that it does not work with large files over 300MB.

Calling Make file in nested folder via Node.js

I have a complicated MakeFile file I want to call as part of my node.js app, the make file is a couple of directories deep from root. I know I need to spawn a 'make' chile process but moving node into the sub directory to call the make im not so sure about.
Сould you move the make to the nested folder? I would try something like
var util = require('util'),
exec = require('child_process').exec,
child;
child = exec('cd samples/nestedmake && make',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
(copied with minimal changes from Node Child Processes documentation).

Resources