【问题标题】:ssh persistent sessions with node.js使用 node.js 的 ssh 持久会话
【发布时间】:2014-02-22 14:15:23
【问题描述】:

我正在使用 node.js,我正在尝试在 Web 浏览器中嵌入控制台以在远程服务器中工作。 Web 应用程序执行连接,因此用户无需执行ssh username@host,只需键入命令即可。

我已经尝试过 node.js 的 ssh2 模块和其他使用 ssh2 的模块。但我总是遇到同样的问题。每次我使用exec() 以编程方式执行命令时,ssh 会话都会重新启动。我会用一个例子更好地解释它。

> ls

返回主目录的内容,主目录中的目录之一是mydir

> cd mydir
> ls

再次返回我的主目录的内容,因为在执行命令后 ssh 会话被关闭/重新启动。

任何可以完成这项工作的 node.js 库?甚至是不同于 javascript 的其他技术库?

编辑: 其他澄清示例,使用 node.js 的模块 ssh-exec 服务器必须使用 ssh 在其他机器上执行一些命令。服务器中的一个函数包含以下代码

var c = exec.connection('username@host.com'); // It takes the ssh key from the default location
exec('cd mydir', c).pipe(process.stdout);
exec('ls -lh', c).pipe(process.stdout);

如您所见,我并没有在第一个exec 之后结束连接,但我获得的输出是主目录的内容而不是 mydir 目录的内容,因为在每个exec 之后都会重置 ssh 会话。

【问题讨论】:

    标签: javascript node.js shell ssh


    【解决方案1】:

    node.js 的 ssh2 模块的维护者提供了解决方案。

    使用方法shell()代替方法exec()。

    shell() 方法与我们正在连接的服务器创建一个交互式会话。 方法shell() 提供一个流作为其回调的参数(如方法exec())。

    与使用exec() 时一样,stream.on('data', function(data, extended) {...}); 可用于获取命令的输出。但是,在这种情况下,要向您连接的机器提供命令(输入),您需要使用stream.write(yourcommand+'\n');

    PS。随意编辑以提高答案的准确性。

    【讨论】:

      【解决方案2】:

      我不得不猜测一下,但你会做类似child = exec('ssh username@host ls') 的事情吗?

      你可以这样做

      child = exec('ssh username@host');
      

      预先并在浏览器的“循环”中

      child.stdin.write('ls\n');
      

      完成后,关闭stdin:

      child.stdin.end()
      

      这也完成了子进程。

      【讨论】:

      • 不是这样的。我使用 ajax 在服务器中调用一个函数,该函数采用先前创建的 shh 连接并执行 connection.exec('cd mydir')。稍后,其他ajax请求用其他命令调用该函数;该函数执行connection.exec('ls') 的命令。我的输出没有问题,得到它并打印它很好,但输出不是预期的(它不是 mydir 的内容,而是主目录的内容),因为 ssh 会话似乎被重置了每次执行后:(
      • 变化不大。你的 exec 调用仍然有一个新的上下文。您需要在服务器端打开 ssh 连接并保持打开状态(如果需要,还需要空闲超时)。
      • 我想解释的是那行不通。如果我在服务器端以编程方式打开一个连接,然后立即执行connection.exec('cd mydir') 并立即执行connection.exec('ls'),则不会出现预期结果,因为每次执行后似乎都会重置连接。我将编辑我的问题以举例说明。
      • 问题不是连接,而是执行...这个连接是什么类型的?
      • 那么 - 请参阅 David T 的回答。这应该可以解决您的问题。
      【解决方案3】:

      我知道此链接已过时,但我认为如果有人正在寻找解决方案,这可能会对他们有所帮助。

      使用方法 shell() 代替方法 exec()。

      有效。这是另一个解决方案。使用绝对文件路径,即

      conn.exec("mkdir -p /home/user/Direc/{one,two,three}/", function(err, stream) {
              if (err) throw err;
              stream.on('data', function(data) {
                  console.log('STDOUT: ' + data);
              }).stderr.on('data', function(data) {
                  console.log('STDERR: ' + data);
              });
          });
      
      conn.exec("ls -la /home/user/", function(err, stream) {
          if (err) throw err;
          stream.on('close', function(code, signal) {
              console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
              conn.end();
          }).on('data', function(data) {
              console.log('STDOUT: ' + data);
          }).stderr.on('data', function(data) {
              console.log('STDERR: ' + data);
          });
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-20
        • 2011-07-11
        • 2014-11-21
        • 2011-07-06
        • 1970-01-01
        • 2012-11-20
        • 2012-03-17
        • 1970-01-01
        相关资源
        最近更新 更多