forked from allenhwkim/proctree
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
72 lines (62 loc) · 2.46 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
'use strict';
var execSync = require('child_process').execSync;
var mainPid = require('yargs').argv._[0];
class Process {
constructor(pid, name, level=0) {
[this.pid, this.name, this.level, this.children] = [pid, name, level, []];
}
}
let PsTree = {
// setup children properties of the given processObj;
_buildProcessTree(processObj) {
(typeof processObj === 'number') && (processObj = this.getProcessTree(processObj));
try {
let lines = execSync(`pgrep -lfP ${processObj.pid}`).toString().split('\n').filter(e => e);
lines.forEach(line => {
let [_, pid, name] = line.match(/^(\d+) (.*)$/);
processObj.children.push(new Process(pid, name, processObj.level + 1));
processObj.children.forEach(el => this._buildProcessTree(el));
});
} catch(e) {} // pgrep fails when no children found
return processObj;
},
_txtProcessTree(processObj) {
(typeof processObj === 'number') && (processObj = this.getProcessTree(processObj));
let prefix = Array(processObj.level).fill(' ').join('');
let name = processObj.name.length > 80 ? processObj.name.substring(0, 77)+' ...': processObj.name;
let output = `${prefix} * ${processObj.pid} ${name}\n`;
processObj.children.forEach(child => output += this._txtProcessTree(child));
return output;
},
getPids(processObj, pidsByLevel = []) {
(typeof processObj === 'number') && (processObj = this.getProcessTree(processObj));
pidsByLevel[processObj.level] = pidsByLevel[processObj.level] || [];
pidsByLevel[processObj.level].push(processObj.pid);
processObj.children.forEach(child => this.getPids(child, pidsByLevel));
return pidsByLevel;
},
getProcessTree(pid) {
try {
let psOutput = execSync(`ps -p ${pid} -o "pid=,command="`).toString().trim();
let [_, processId, processName] = psOutput.match(/^(\d+) (.*)$/);
let processObj = new Process(processId, processName);
this._buildProcessTree(processObj);
return processObj;
} catch(e) {
console.error('Invalid process id.', e.message);
process.exit(2);
}
},
treeKill(pid) {
let pids = this.getPids(pid).reduce( (s, e) => s.concat(e)).reverse();
execSync(`kill -9 ${pids.join(' ')}`);
return `killed ${pids.join(' ')}`;
},
show(pid) {
console.log( this._txtProcessTree(pid) );
}
}
if (require.main === module) {
mainPid ? PsTree.show(mainPid) : console.error('invalid process id') && process.exit(1);
}
module.exports = PsTree;