【问题标题】:Sending a Terminate (Ctrl+C) Command in Node.js SSH2在 Node.js SSH2 中发送终止 (Ctrl+C) 命令
【发布时间】:2016-06-06 23:20:51
【问题描述】:

我正在使用 Node.js SSH2 模块(https://github.com/mscdex/ssh2)。 myScript.py 连续执行。如何在保持 SSH 连接处于活动状态的同时停止它?

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'
});

【问题讨论】:

    标签: node.js ssh


    【解决方案1】:

    我们的研究组也遇到了同样的问题,我们的解决方案是在第一次执行命令时获取远程进程的进程ID,然后在需要时将其杀死。

    如果您只使用kill [pid] 命令,python 进程似乎会继续在后台分离,因此我们在下面的解决方案中使用了pkill -g [pid] 命令。在其他情况下,这可能不同或相同。但我想知道你应该尝试这两种情况如果一个不适合你是件好事。

    这是我们的(简化的)解决方案。当然,在 5 秒后杀死每个 exec 命令是没有意义的......但你会明白的(以及一个安全的 pid/conn 重用范围):

    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'
    });
    

    【讨论】:

      【解决方案2】:

      问题在于,并非所有 SSH 服务器都支持 signal() 发送的数据包,这包括撰写本文时的 OpenSSH。

      幸运的是,对于 SIGINT,您通常可以通过将 '\x03' 写入流来获得预期的行为。

      【讨论】:

      • stream.write('\x03');不做任何事情,也不会引发错误。 c.exec('\x03'....... 也是如此
      • 嗯,你总是可以用stream.end(); 结束流,这应该总是杀死远程端的进程。
      • 在我调用 stream.end(); 之后我应该调用 c.exec('python myScript.py', function(err, stream) {... 重新启动脚本吗?
      • 是的,如果您需要重新启动它应该可以正常工作。
      • 如果你真的需要,我想你可以这样做。我会确保在调用 .end() 后取消设置变量,但要防止在同一流上多次调用 .end()。
      猜你喜欢
      • 1970-01-01
      • 2013-12-30
      • 2023-02-09
      • 2015-11-27
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      • 2017-06-18
      • 2021-09-22
      相关资源
      最近更新 更多