JAVA SCRIPT - Accessing Command-Line Functionality Within a Node Application - Web Development and Design | Tutorial for Java, PHP, HTML, Javascript JAVA SCRIPT - Accessing Command-Line Functionality Within a Node Application - Web Development and Design | Tutorial for Java, PHP, HTML, Javascript

Breaking

Post Top Ad

Post Top Ad

Thursday, March 14, 2019

JAVA SCRIPT - Accessing Command-Line Functionality Within a Node Application

Accessing Command-Line Functionality Within a Node Application


Problem

You want to access command-line functionality, such as ImageMagick, from within a Node application.

Solution

Use Node’s child_process module. For example, if you want to use ImageMagick’s identify, and then print out the data to the console, use the following:


var spawn = require('child_process').spawn,
 imcmp = spawn('identify',['-verbose', 'osprey.jpg']);
imcmp.stdout.on('data', function (data) {
 console.log('stdout: ' + data);
});
imcmp.stderr.on('data', function (data) {
 console.log('stderr: ' + data);
});
imcmp.on('exit', function (code) {
 console.log('child process exited with code ' + code);
});

EXPLAIN

The child_process module provides four methods to run command-line operations and process returned data:

• spawn(command, [args], [options]): This launches a given process, with op‐ tional command-line arguments, and an options object specifying additional in‐ formation such as cwd to change directory and uid to find the user ID of the process. 

• exec(command, [options], callback): This runs a command in a shell and buf‐ fers the result. 

• execFile(file, [args],[options],[callback]): This is like exec() but exe‐ cutes the file directly. 

• fork(modulePath, [args],[options]): This is a special case of spawn(), and spawns Node processes, returning an object that has a communication channel built in. It also requires a separate instance of V8 with each use, so use sparingly.

The child_process methods have three streams associated with them: stdin, stdout, and stderr. The spawn() method is the most widely used of the child_process meth‐ ods, and the one used in the solution. 

From the solution top, the command given is the ImageMagick identify command-line application, which can return a wealth of in‐ formation about an image. In the args array, the code passes in the --verbose flag, and the name of the image file. 

When the data event happens with the child_pro cess.stdout stream, the application prints it to the console. The data is a Buffer that uses toString() implicitly when concatenated with another string. If an error happens, it’s also printed out to the console.

 A third event handler just communicates that the child process is exiting. If you want to process the result as an array, modify the input event handler: 


imcmp.stdout.on('data', function (data) {
 console.log(data.toString().split("\n"));
});


Now the data is processed into an array of strings, split on the new line within the identify output. If you want to pipe the result of one process to another, you can with multiple child processes.

 If, in the solution, I want to pipe the result of the identify command to grep, in order to return only a subset of the information,

 I can do this with two different spawn() commands In the code, the resulting data from the identify command is written to the stdin input stream for the grep command, and the grep’s data is then written out to the console.

Spawning two child processes to pipe the results of one command to another:


var spawn = require('child_process').spawn,
 imcmp = spawn('identify',['-verbose', 'fishies.jpg']),
 grep = spawn('grep', ['Resolution']);
imcmp.stdout.on('data', function (data) {
 grep.stdin.write(data);
});
imcmp.stderr.on('data', function (data) {
 console.log('stderr: ' + typeof data);
});
grep.stdout.on('data', function (data) {
 console.log('grep data: ' + data);
});
grep.stderr.on('data', function (data) {
 console.log('grep error: ' + data);
});
imcmp.on('close', function (code) {
 console.log('child process close with code ' + code);
 grep.stdin.end();
});
grep.on('close', function(code) {
 console.log('grep closes with code ' + code);
});

In addition, the application also captures the close event when the streams terminate (not necessarily when the child processes exit). In the close event handler for the identify child process, the stdin.end() method is called for grep to ensure it terminates.

The result of running the application on the test image is:


child process close with code 0
grep data: Resolution: 240x240
 exif:ResolutionUnit: 2
 exif:XResolution: 2400000/10000
 exif:YResolution: 2400000/10000
grep closes with code 0




Note the order: the original identify child process stream terminates once its data is passed to the grep command, which then does its thing and prints out the target data (the photo resolution).

Then the grep command’s close event is processed. Instead of using a child process, if you have either GraphicsMagick or ImageMagick installed, you can use the gm Node module for accessing the imaging capability. Just install it as:


npm install gm


Of course, you can still use the child process, but using the GraphicsMagick module can be simpler.

Using Child Processes with Windows


The solution demonstrates how to use child processes in a Linux environment. There are similarities and differences between using child processes in Linux/Unix, and using them in Windows. 

In Windows, you can’t explicitly give a command with a child process; you have to invoke the Windows cmd.exe executable and have it perform the process. In addition, the first flag to the command is /c, which tells cmd.exe to process the command and then terminate. 

Borrowing an example from Learning Node (O’Reilly), in the following code, the cmd.exe command is used to get a directory listing, using the Windows dir command:


var cmd = require('child_process').spawn('cmd', ['/c', 'dir\n']);
cmd.stdout.on('data', function (data) {
 console.log('stdout: ' + data);
});
cmd.stderr.on('data', function (data) {
 console.log('stderr: ' + data);
});
cmd.on('exit', function (code) {
 console.log('child process exited with code ' + code);
});

No comments:

Post a Comment

Post Top Ad