Giter VIP home page Giter VIP logo

node-tree-kill's Introduction

Tree Kill

Kill all processes in the process tree, including the root process.

Examples

Kill all the descendent processes of the process with pid 1, including the process with pid 1 itself:

var kill = require('tree-kill');
kill(1);

Send a signal other than SIGTERM.:

var kill = require('tree-kill');
kill(1, 'SIGKILL');

Run a callback when done killing the processes. Passes an error argument if there was an error.

var kill = require('tree-kill');
kill(1, 'SIGKILL', function(err) {
    // Do things
});

You can also install tree-kill globally and use it as a command:

tree-kill 1          # sends SIGTERM to process 1 and its descendents
tree-kill 1 SIGTERM  # same
tree-kill 1 SIGKILL  # sends KILL instead of TERMINATE

Methods

require('tree-kill')(pid, [signal], [callback]);

Sends signal signal to all children processes of the process with pid pid, including pid. Signal defaults to SIGTERM.

For Linux, this uses ps -o pid --no-headers --ppid PID to find the parent pids of PID.

For Darwin/OSX, this uses pgrep -P PID to find the parent pids of PID.

For Windows, this uses 'taskkill /pid PID /T /F' to kill the process tree. Note that on Windows, sending the different kinds of POSIX signals is not possible.

Install

With npm do:

npm install tree-kill

License

MIT

Changelog

[1.2.2] - 2019-12-11

Changed

  • security fix: sanitize pid parameter to fix arbitrary code execution vulnerability

[1.2.1] - 2018-11-05

Changed

  • added missing LICENSE file
  • updated TypeScript definitions

[1.2.0] - 2017-09-19

Added

  • TypeScript definitions

Changed

  • kill(pid, callback) works. Before you had to use kill(pid, signal, callback)

[1.1.0] - 2016-05-13

Added

  • A tree-kill CLI

[1.0.0] - 2015-09-17

Added

  • optional callback
  • Darwin support

node-tree-kill's People

Contributors

billiegoose avatar borekb avatar jub3i avatar linusu avatar orodley avatar pkrumins avatar robcresswell avatar twolfson avatar ultcombo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

node-tree-kill's Issues

Not functional on Docker Alpine

Hello,

Trying to use this module for killing a process tree in Docker that is built on Alpine image. Unfortunately, the module fails to create a process tree, since ps does not support some of the flags that the module is relying on: --no-headers and --ppid. This results in a process returning non-zero code. Module interprets non-zero as "no child processes" and swallows the error silently.

I was trying to find a way to change the command in buildProcessTree so that it simulates the same output. Removing header is easy - we can pass the names of the columns with -o, removing the header completely:

/usr/src/app # ps -opid=""
    1
   23
   49
   67

But lack of --ppid filter support making it slightly more challenging. My Linux knowledge is not enough to tell if manually filtering by ppid in the following command would do the trick:

/usr/src/app # ps -opid="" -oppid=""
    1     0
   23     1
   49     0
   68    49

If that's the case, it would probably be the most portable version (except for the cases when ps is not present at all as described in #36

If there's an ambition to rewrite this part of the code, I am happy to collaborate ๐Ÿ™‚

npm repo issues

In the version you get from npm

  • some of the files are marked as executable
  • there are some duplicate files ending in ~ (backups from some text editor I think)
  • there is a test.js file included which is not needed?

'taskkill' is not recognized as an internal or external command

๐Ÿ‘‹ Hi, we're using tree-kill in Stryker. We occasionally see this error when running tree-kill on windows:

Command failed: taskkill /pid 14880 /T /F
'taskkill' is not recognized as an internal or external command,

It might not be reasonable to assume that taskkill exists on the path. Would a workaround to a simple process.kill be something that you're interested in? Or maybe someone knows another way to do this?

Does not work properly in Windows

I spawn a python Process in my Electron App. On the python process runs a Flask server. In my Electron App I spawn the Python process with

const { spawn } = require('child_process');
const treeKill = require('tree-kill');
const path = require('path');

const projectPath = path.join(__dirname, '../');
const pathToPython = path.join(projectPath, '/Venv/Scripts/python');
const pythonOptions = [path.join(projectPath, '/pythonBackend/app.py')];

let ls = spawn(pathToPython, pythonOptions);

I later kill the process with

treeKill(ls.pid);

I can see in the Process Explorer from Microsoft that the tree also gets killed,but after a milisecond, the python process somehow respawns as a standalone process.

If I kill the exact same process tree in the Process Explorer from Windows, then the tree gets killed and there is no crazy respawn of the python process. I don't know why its respawning with the tree-kill module. Any Ideas?

UPDATE
I use now the module tree-kill-promise. https://www.npmjs.com/package/tree-kill-promise This worked for me.

Security issue [npm audit]

Versions of tree-kill prior to 1.2.2 are vulnerable to Command Injection. The package fails to sanitize values passed to the kill function. If this value is user-controlled it may allow attackers to run arbitrary commands in the server. The issue only affects Windows systems.

https://www.npmjs.com/advisories/1432

"Graceful" process killing on Windows (something akin to SIGINT)

I get that Windows doesn't handle POSIX signals like Linux, but seems like the process just gets killed so you can't do a graceful shutdown.

Any way to do this? Let's say I have a process that's doing it's own thing and want to kill it, but before it does, I want it to do something:

'use strict';

var fs = require('fs');
var path = require('path');

if (process.platform === 'win32') {
  console.log('win32 true');
  var rl = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  rl.on('SIGINT', function() {
    process.emit('SIGINT');
  });
}

process.on('SIGINT', function() {
  console.log('SIGINT');
  process.exit();
});

var filepath = path.resolve(__dirname, 'pid.txt');

fs.writeFile(filepath, process.pid);

var i = 0;
setInterval(function () {
  console.log(i++);
}, 1000);

Callback support

Right now you have no information about when actually all processes were killed: if taskkill/ps took time, there is no chance for user to know about it. Function is neither sync, nor calls callback.

Does not kill child process on MacOS

In some cases I want to kill a child process spawned from node, but even if I use this package giving the process's PID number, the process lives happily and does not close. Any idea?

Issue with providing callback but no signal

When using kill(), if I pass it the pid and a callback, but no signal as in this example:

kill(process.pid, function(err){
    if(err){
        console.log(err);
    }
    // do something
});

I get the following error:

Error: Unknown signal: function (err){
            if(err){
                console.log(err);
            } else {
	            console.log("Child process killed.");
            }
        }

It looks like the function can't handle not being given a signal if it is given a callback function. If I do the same code, but with the default signal 'SIGTERM' as well, it works fine.

I would offer to fix but I don't really know how (would love to learn though).

Tree kill not killing spawned docker processes

Is tree kill meant to kill all child processes? Even if they are docker processes? I am trying to kill a child process that runs docker commands but kill tree only kills the node process. I will attach some code snippets but kill(childID) is not killing the sub processes.

const kill = require('tree-kill'); / npm install tree-kill --save

I create a bash script and spawn a child process to run it.
`let buildScript = "docker build -t " + image_name + " . \n";

buildScript += "docker run -v /var/run/docker.sock:/var/run/docker.sock " + image_name + " \n";

buildScript += "docker rmi " + image_name + " \n";

const dockerBuild = spawn('bash', ['-c', buildScript]);

console.log(dockerBuild.pid);

childPID = dockerBuild.pid;`

then to try to kill it I run
`console.log('child piid ======', childPID);

kill(childPID, 'SIGKILL', function(err) {
    console.log('error here ------', err);
});` 

The childPID comes in correctly and the node process does get killed I believe but docker run and build continue to run even after I have called the tree kill with the childPID. Any help or suggestions would be great thank you!

More friendly error message when `ps` is not available

If no ps program is available on Linux, this package throws a generic ENOENT error. When this library is a dependency of dependency, its not immediately clear where from exactly the error is coming. For ease of debugging, maybe a custom error should be thrown, with message like "tree-kill package needs ps command to be available in PATH" or similar.

events.js:186
      throw er; // Unhandled 'error' event
      ^

Error: spawn ps ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:264:19)
    at onErrorNT (internal/child_process.js:456:16)
    at processTicksAndRejections (internal/process/task_queues.js:80:21)
Emitted 'error' event on ChildProcess instance at:
    at Process.ChildProcess._handle.onexit (internal/child_process.js:270:12)
    at onErrorNT (internal/child_process.js:456:16)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  errno: 'ENOENT',
  code: 'ENOENT',
  syscall: 'spawn ps',
  path: 'ps',
  spawnargs: [ '-o', 'pid', '--no-headers', '--ppid', 185 ]
}

see nestjs/nest-cli#484

Uncaught Error: kill ESRCH

On node 4.6 I'm getting: Uncaught Error: kill ESRCH . This means the pid does not exist.
However I am checking to see if the process exists before killing it:

           if( process.kill( pid, 0) ){ //checks if the pid exists
             kill( pid )
           }

This only happens when I'm starting and killing processes back to back in a test runner.

Any clues on what might cause this?

TypeError: Cannot read property 'on' of undefined

I use onchange package which crash in tree-kill.
Stack trace:

<folder>/node_modules/tree-kill/index.js:78
    ps.stdout.on('data', function (data) {
             ^

TypeError: Cannot read property 'on' of undefined
    at buildProcessTree (/***/node_modules/tree-kill/index.js:78:14)
    at /***/node_modules/tree-kill/index.js:99:11
    at Array.forEach (native)
    at ChildProcess.onClose (/***/node_modules/tree-kill/index.js:94:31)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:192:7)
    at maybeClose (internal/child_process.js:890:16)
    at Socket.<anonymous> (internal/child_process.js:334:11)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:189:7)

No error given when kill fails

Given the following program:

process.on('SIGTERM', () => console.error('Ignoring'));

let n = 0;
setInterval(()=> console.log(n++), 2*1000);

I have tried to kill it using treeKill via something like

treeKill(myPID, (err) => {console.log(typeof err)})

Here I get no err because, like kill on linux, the exit code is 0 as the signal was sent successfully. Is this expected? I assume so, but it makes ensuring a process is dead a little more complex.

In Ubuntu the root process is not get killed

In Ubuntu the root process is not get killed. It is attempted to be killed of, but never does. I suspect it has something to do with the child processes still being alive by that moment. Btw, SIGKILL signal does the job perfectly right away. Why do we even need to build up a tree and kill processes one by one?

Package name shows up in inclusive language scanner (kill)

Your package name shows up in our corp inclusive language scanner because of the word "kill". Please consider changing the name and deprecating the old package

The scanner included the following words for suggested replacement:

force quit,
force exit,
terminate,
stop,
end,
halt,
cancel

node-tree-terminate or node-tree-force-exit are two nice candidates

Thanks.

[feature request] support `sync` mode

Hi, thanks for your helpful module! This is a feature request. Can we have sync mode so I can correctly block my other code executions while using? For example:

const treeKill = require('tree-kill').sync;

console.log('try kill', pid);
treeKill(pid);
console.log(pid, 'killed')

process not killed with a git bash on windows.

Hi,

I'm using an Angular wep application launched from a git bash terminal with ng serve.
When I want to exit the Angular web app with a Ctrl+C, the Angular @ngtools using tree-kill as a dependency send the following command treeKill(this._typeCheckerProcess.pid, 'SIGTERM') with the good pid. But tree-kill try to kill process by a taskkill command not recognized by git bash.
The issue is that it's the process.platform (here win32) which is identified and not the prompt.

Therefore, to resolve this issue, we have to identified git bash terminal and execute the following command exec('tskill' + pid) instead.

race condition

It can happen that ps emits the exit event, but ps.stdout.on('data', cb) has not yet emptied the stream into allData. This happens because exit event "stdio streams might still be open." So the result is that a call to the exported function just ends up hanging sometimes because buildProcessTree() is not called again.

I've made a patched version relying on ps.stdout.on('close', cb) event instead.

Kill processes via `/proc` if `ps` is not available

Semi-related to #29

We recently ran into tree-kill failures because AWS Lambda's Linux container (Amazon Linux 2) does not have ps. I was able to work around this by detecting the Lambda environment and attempting to (mis)use the /proc dir to kill processes: https://github.com/architect/sandbox/pull/594/files

(Related: super open to feedback on whether you feel this approach was properly executed in the PR linked above. It's a bit mysterious how Node nested spawns, execs, and forks influence /proc, and whether enumerating and killing /proc/<pid>/task/<tid>s is as effective as relying on ps โ€“ but this approach does correctly terminate child processes in Lambda and non-Lambda Linux.)

Would you be amenable to a PR that makes a best effort to use ps on Linux, but then backs off to using /proc if a spawn ps ENOENT error is thrown?

Consider using pidtree package

Currently this package recursively kill processes level by level spawning the ps or pgrep a lot of times.

I've built this package that maybe can help to improve performance.
https://github.com/simonepri/pidtree

My benchmarks shows that is really fast (~5-10 ms per call regardless of how big the sub-tree is) but I don't know if it would be adapt for the use of this package.

What's the advantage of calling ps or pgrep multiple times instead of parsing the tree just calling ps once? Memory efficiency? Or it was just simpler to implement?

See also:
Unitech/pm2#3554 (comment)

cc: @soyuka

Running tree kill with superuser via command interface

Hi,

I have a use case where I need to run tree-kill with elevated user privileges to kill a parent and its child processes.

One way to get this use case to work with tree-kill is to call it from the command line like this:

sudo treeKill [pid]

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.