You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取ExpressJS中simple-ssh远程SSH命令执行的输出结果

解决simple-ssh回调外部无法获取执行结果的问题

这个问题其实是异步编程里的典型场景——simple-ssh的API是基于回调的,你在out回调里赋值的arrayOfVersion,在回调外直接访问时,代码执行顺序根本还没走到赋值那一步!因为SSH命令的执行是异步的,ssh.exec().start()调用后会立刻继续执行后面的代码,而out回调要等远程命令执行完成、拿到输出后才会触发。

下面给你两种常用的解决方案:

方案1:用自定义回调函数处理结果

把你后续对版本列表的操作封装成一个函数,在out回调里拿到结果后直接调用这个函数,把结果传进去:

// 定义处理版本列表的函数
function processVersions(versions) {
  // 这里写你后续要做的操作,比如打印、过滤、存数据库等等
  console.log('远程获取到的版本列表:', versions);
  // 举个例子:过滤掉空行(因为ls输出最后会有个空行)
  const validVersions = versions.filter(v => v.trim() !== '');
  console.log('清理后的有效版本:', validVersions);
}

// 执行SSH命令
ssh.exec('ls Documents/versions', { 
  out: function(stdout) { 
    const arrayOfVersion = stdout.split("\n");
    // 拿到结果后立刻调用处理函数
    processVersions(arrayOfVersion);
  },
  err: function(stderr) {
    console.error('执行SSH命令出错:', stderr);
  }
}).start();

方案2:用Promise封装+async/await(推荐,代码更易读)

把整个SSH命令的执行逻辑封装成一个Promise,这样就能用async/await语法,让异步代码看起来像同步代码一样:

// 封装获取远程版本的Promise函数
function getRemoteVersions() {
  return new Promise((resolve, reject) => {
    ssh.exec('ls Documents/versions', {
      // 成功拿到输出时resolve结果
      out: function(stdout) {
        const arrayOfVersion = stdout.split("\n");
        resolve(arrayOfVersion);
      },
      // 命令出错时reject错误信息
      err: function(stderr) {
        reject(new Error(`SSH命令执行失败: ${stderr}`));
      },
      // 整个SSH会话结束的回调(可选)
      exit: function(code) {
        if (code !== 0) {
          reject(new Error(`SSH会话异常退出,退出码: ${code}`));
        }
      }
    }).start();
  });
}

// 在async函数中使用await获取结果
async function handleRemoteTask() {
  try {
    // 等待Promise完成,拿到版本列表
    const arrayOfVersion = await getRemoteVersions();
    // 这里就可以直接用arrayOfVersion做后续操作了
    console.log('获取到的版本列表:', arrayOfVersion);
    // 比如继续执行其他依赖这个结果的逻辑
    // doSomethingElse(arrayOfVersion);
  } catch (error) {
    // 捕获并处理错误
    console.error('操作失败:', error.message);
  }
}

// 调用执行函数
handleRemoteTask();

为什么原来的方式不行?

简单说就是执行顺序的问题:

  1. 你调用ssh.exec().start(),SSH开始连接执行命令,但这个过程是异步的,不会阻塞后续代码。
  2. 你立刻去访问arrayOfVersion,这时候out回调还没执行,变量要么是未定义,要么是初始值。
  3. 等SSH命令执行完,out回调触发,这时候才会给arrayOfVersion赋值,但这时候后续代码早就执行完了。

所以核心是要把依赖异步结果的逻辑,放到结果就绪之后才执行——不管是用回调嵌套,还是Promise+async/await,本质都是这个思路。

内容的提问来源于stack exchange,提问作者Ben Mustapha Sabrine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:16:59