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.