Skip to content
Advertisement

How to declare a global array within an exec in javascript

I’m writing a js script to locate all pid files on a server, extract the pids and then run ‘ ps -fp {pid} ‘ on each of it and extract the memory usages.

This is what I’ve got so far:

var exec = require('child_process').exec;

exec('(cd ~/; find . -type f -name "*.pid" )', (error, stdout, stderr) => {
    if (error) {
      return 1
    }
    var fileps = stdout.toString().split('n');
    fileps.pop()  
    var pidsarr = new Array;
    
    function getpid(path) {
    var command = `(cd ~/; cat ${path} )`;
    exec(command, (error, stdout, stderr) => {
        if (error) {
          return 1
        }
        pid = parseInt(stdout.toString());
        pidsarr.push(pid);
    });
    }

    fileps.forEach(getpid);    
    console.log(pidsarr); 
});

The issue is pidsarr is not getting updated, probably since it’s not declared global or something to do with exec not allowing to write to external objects.

Any way to get my pidsarr array to get appended each run?

Advertisement

Answer

pidsarr is appended to for each run. However, you just schedule the runs in the background and don’t wait for them to finish, so you don’t see the final value.

You can verify this with a setTimeout(() => console.log(pidsarr), 1000);

To make it wait, you can either rewrite in terms of execSync, or have getpid return a Promise, then wait for all the promises to resolve:

var exec = require('child_process').exec;

exec('(cd ~/;  find . -type f -name "*.pid")', (error, stdout, stderr) => {
    if (error) {
      return 1
    }
    var fileps = stdout.toString().split('n');
    fileps.pop()
    var pidsarr = new Array();

   function getpid(path) {
      var command = `(cd ~/; cat ${path} )`;
      return new Promise((resolve, fail) => {
        exec(command, (error, stdout, stderr) => {
          if (error) {
            fail();
          }
          pid = parseInt(stdout.toString());
          pidsarr.push(pid);
          resolve();
        });
      })
    }

    Promise.all(fileps.map(getpid)).then(() => console.log(pidsarr));
});

Note that it’s bad practice to invoke find and cat like this. It’s faster, more robust, and more portable to use glob and fs to find and read files without external tools.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement