pidtree.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #!/usr/bin/env node
  2. 'use strict';
  3. var os = require('os');
  4. var pidtree = require('..');
  5. // The method startsWith is not defined on string objects in node 0.10
  6. // eslint-disable-next-line no-extend-native
  7. String.prototype.startsWith = function(suffix) {
  8. return this.substring(0, suffix.length) === suffix;
  9. };
  10. function help() {
  11. var help =
  12. ' Usage\n' +
  13. ' $ pidtree <ppid>\n' +
  14. '\n' +
  15. 'Options\n' +
  16. ' --list To print the pids as a list.\n' +
  17. '\n' +
  18. 'Examples\n' +
  19. ' $ pidtree\n' +
  20. ' $ pidtree --list\n' +
  21. ' $ pidtree 1\n' +
  22. ' $ pidtree 1 --list\n';
  23. console.log(help);
  24. }
  25. function list(ppid) {
  26. pidtree(ppid === undefined ? -1 : ppid, function(err, list) {
  27. if (err) {
  28. console.error(err.message);
  29. return;
  30. }
  31. console.log(list.join(os.EOL));
  32. });
  33. }
  34. function tree(ppid) {
  35. pidtree(ppid, {advanced: true}, function(err, list) {
  36. if (err) {
  37. console.error(err.message);
  38. return;
  39. }
  40. var parents = {}; // Hash Map of parents
  41. var tree = {}; // Adiacency Hash Map
  42. while (list.length > 0) {
  43. var element = list.pop();
  44. if (tree[element.ppid]) {
  45. tree[element.ppid].push(element.pid);
  46. } else {
  47. tree[element.ppid] = [element.pid];
  48. }
  49. if (ppid === -1) {
  50. parents[element.pid] = element.ppid;
  51. }
  52. }
  53. var roots = [ppid];
  54. if (ppid === -1) {
  55. // Get all the roots
  56. roots = Object.keys(tree).filter(function(node) {
  57. return parents[node] === undefined;
  58. });
  59. }
  60. roots.forEach(function(root) {
  61. print(tree, root);
  62. });
  63. });
  64. function print(tree, start) {
  65. function printBranch(node, branch) {
  66. var isGraphHead = branch.length === 0;
  67. var children = tree[node] || [];
  68. var branchHead = '';
  69. if (!isGraphHead) {
  70. branchHead = children.length > 0 ? '┬ ' : '─ ';
  71. }
  72. console.log(branch + branchHead + node);
  73. var baseBranch = branch;
  74. if (!isGraphHead) {
  75. var isChildOfLastBranch = branch.slice(-2) === '└─';
  76. baseBranch = branch.slice(0, -2) + (isChildOfLastBranch ? ' ' : '| ');
  77. }
  78. var nextBranch = baseBranch + '├─';
  79. var lastBranch = baseBranch + '└─';
  80. children.forEach(function(child, index) {
  81. printBranch(
  82. child,
  83. children.length - 1 === index ? lastBranch : nextBranch
  84. );
  85. });
  86. }
  87. printBranch(start, '');
  88. }
  89. }
  90. function run() {
  91. var flag;
  92. var ppid;
  93. for (var i = 2; i < process.argv.length; i++) {
  94. if (process.argv[i].startsWith('--')) {
  95. flag = process.argv[i];
  96. } else {
  97. ppid = process.argv[i];
  98. }
  99. }
  100. if (ppid === undefined) {
  101. ppid = -1;
  102. }
  103. if (flag === '--list') list(ppid);
  104. else if (flag === undefined) tree(ppid);
  105. else help();
  106. }
  107. run();