NodeJs Example of Scripting Linux command line calls

This shows an approach to using NodeJs for scripting linux command line calls. The goal is to try to use a more functional programming approach. A chain of promises is used. Each call to the linux command line is asynchronous so JavaScript promises provide a clean way to manage this.

The JavaScript library lodash is used to provide functionality.


'use strict';

module.exports.fileProcessor = (() => {

    const _ = require('lodash');
    const util = require('util')
    const exec = require('child_process').exec;
    var child;

    this._e = (cmd) => {
        return new Promise((resolve, reject)  => {
            child = exec(cmd, (error, stdout, stderr) =>{
                resolve(stdout);
                if (error !== null || stderr != null) {
                    console.log("---errors: ")
                    console.log("error: " + error);
                    console.log("stderr: " + stderr)
                    reject(stderr);
                }
              });
        });
    }

    const helpers = require ('../helpers.js');

    this.run = (filePath, newFileExtension) => {

        const thenFn = (fileNames) => {

            var zipFileNames = _.map(fileNames, (fileName) => {
                var newFileName = fileName;
                if (newFileExtension != undefined) {
                    var name = fileName.split(".")[0];
                    newFileName = name + newFileExtension;
                }
                return newFileName;
            });

            const copyPromises = _.map(_.zip(fileNames, zipFileNames), (pair) =>{
                return new Promise((resolve, reject) => {
                    const fileName = pair[0];
                    const newFileName = pair[1];
                    const cmd = "cp '" + fileName + "' '" + newFileName + "'";
                    this._e(cmd)
                    .then((e)=> {
                        resolve((e)=> console.log("copied " + e));
                    }); 
                });
            });

            var lastPromise = _.last(copyPromises);

            const mkDirPromises = _.map(fileNames, (fileName) =>{
                return new Promise((resolve) => {
                    var name = fileName.split(".")[0];
                    const cmd = "mkdir '" + name + "'";
                    this._e(cmd)
                    .then((e)=> {
                        resolve((e)=> console.log("mkdir " + e));
                    });
                });
            });

            const moveFilePromises = _.map(_.zip(fileNames, zipFileNames), (pair) =>{
                return new Promise((resolve, reject) => {
                    const dirName = pair[0].split(".")[0];
                    const zipFileName = pair[1];
                    const cmd = "mv '" + zipFileName + "' '" + dirName + "'";
                    console.log(cmd);
                    this._e(cmd)
                    .then((e)=> {
                        resolve((e)=> console.log("moved " + e));
                    }); 
                });
            });

            const extractFilePromises = _.map(fileNames, (fileName) =>{
                return new Promise((resolve, reject) => {
                    const dirName = fileName.split(".")[0];
                    const baseFileName = _.last(dirName.split("/"));
                    const zipFileName = baseFileName + ".zip";
                    const cmd = "cd '" + dirName + "'; " + " tar -xvf '" + zipFileName + "'";
                    console.log(cmd);
                    this._e(cmd)
                    .then((e)=> {
                        resolve((e)=> console.log("extracted " + e));
                    }); 
                });
            });

            lastPromise.then(
             (someVar) => {
                const lastmkDirPromise = _.last(mkDirPromises);
                lastmkDirPromise.then((output) => {
                    const lastmoveFilePromise = _.last(moveFilePromises);
                    lastmoveFilePromise.then((output) => {
                        const lastextractFilePromise = _.last(extractFilePromises);
                        lastextractFilePromise.then();
                    });
                });
             }   
            );      

        };   

        helpers.getFiles(filePath)(thenFn);

    }

})();

the helpers.js class:


module.exports.helpers = (() => {

     this.getFiles = (path) => {
        const _ = require('lodash');
        const ls = require('list-directory-contents');

        return (thenFn) => {
            return new Promise((resolve, reject)  => {
                ls(path, (err, tree) => {
                    var files = [];
                    _.forEach(tree, (value) => {
                        files.push(value);
                    });
                    resolve(files);
                });

            }).then(thenFn);
        }
    };

})();

Example usage from the NodeJs command line REPL:

 var fp1 = require('./fileProcessor.js');
 fp1.run("/some/directory/path",".zip");

Posted on Dec 05, 2017