user2939415 user2939415 - 5 months ago 40
Node.js Question

Sending a Terminate (Ctrl+C) Command in Node.js SSH2

I am using Node.js SSH2 module(https://github.com/mscdex/ssh2). myScript.py executes continuously. How can I stop it while keeping the SSH connection alive?

var Connection = require('ssh2');
var c = new Connection();
c.on('ready', function() {
c.exec('python myScript.py', function(err, stream) {
if (err) throw err;
stream.on('data', function(data, extended) {
//this callback gets called multiple times as the script writes to stdout
console.log((extended === 'stderr' ? 'STDERR: ' : 'STDOUT: ') + data);
allData+=data;
});
});
});
c.connect({
host: xxx.xxx.x.xx,
port: 22,
username: 'user',
password: 'pass'
});

Answer

We got the same problem in our research group and our solution is to fetch the process ID of the remote process when first executing the command and then kill it when needed.

It seems python processes are continuing to live detached in the background if you only use the kill [pid] command, therefore we used the pkill -g [pid] command in our solution below. This might be different or the same in other cases. But I guess it's good to know that you shoud try both cases if one doesn't work for you.

This is our (simplified) solution. Of course it does not make sense to kill every exec command after 5 seconds... but you will get the idea (and a safe pid/conn scope for reuse):

var Connection = require('ssh2');
var c = new Connection();

function killProcess(conn, pid) {
    setTimeout(function() {
        console.log('Killing PID ' + pid);
        conn.exec('pkill -g ' + pid, function(){});
    }, 5000);
}

c.on('ready', function() {
    // echo $$; gives you the PID, we prepend it with the string
    // "EXEC PID: " to later on know for sure which line we grab as PID
    c.exec('echo "EXEC PID: $$";python myScript.py', function(err, stream) {
        if(err) throw err;
        stream.on('data', function(buffer) {
            var line = '' + buffer; // unbeautiful ;)
            console.log(line);
            if(line.substr(0, 10) === 'EXEC PID: ') {
                killProcess(c, line.substr(10));
            }
        }).on('end', function() {
            console.log('exec killed');
        });
    });
});
c.connect({
  host: xxx.xxx.x.xx,
  port: 22,
  username: 'user',
  password: 'pass'
});
Comments