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

Node.js通过SCP向Unix服务器传文件仅写入首行问题

问题:使用scp2复制文件到远程Unix服务器仅写入第一行

我用Node.js的scp2模块复制文件到远程服务器,但目标文件只保留了源文件的第一行,代码如下:

var client = require('scp2');
var ssh = require('node-sshclient');
var exec = require('child_process').exec;
var waitOn = require('wait-on');
module.exports.copy = function(filename, cb){
  client.scp(filename, 'root:hoplehd@10.20.138.185:22:/opt/', function(err) {
    if (err){
      console.log(err);
    }else{
      console.log("succeeded copying the file to remote server");
    }
  });
};

解决方案

我之前也碰到过类似的坑,大概率是scp2模块本身的兼容性问题——这个库已经有挺长时间没维护了,对某些文件场景(比如大文件、未完全写入的文件、特殊换行符格式)支持不太稳定。给你几个实用的排查和解决方向:

1. 先确认源文件本身的状态

  • 确保要复制的源文件在执行scp操作前已经完全写入磁盘并关闭文件句柄。如果是刚生成的文件,可能还在系统缓存里,scp2读取时只能拿到已经刷到磁盘的第一行。可以先用fs.readFileSync读取本地文件,验证内容是否完整;或者在复制前加个短暂延迟(虽然不是最优解,但能快速排查是不是缓存的问题)。

2. 替换成更稳定的SFTP/SCP库

scp2的bug不少,建议换成维护更活跃的替代方案:

推荐用ssh2-sftp-client(基于ssh2的SFTP客户端)

这个库稳定性强,社区活跃,示例代码如下:

const Client = require('ssh2-sftp-client');
const sftp = new Client();

module.exports.copy = function(filename, cb){
  sftp.connect({
    host: '10.20.138.185',
    port: 22,
    username: 'root',
    password: 'hoplehd'
  })
  .then(() => {
    // 提取文件名,避免路径问题
    const targetFilename = filename.split('/').pop();
    return sftp.put(filename, `/opt/${targetFilename}`);
  })
  .then(() => {
    console.log("succeeded copying the file to remote server");
    sftp.end();
    cb(null);
  })
  .catch(err => {
    console.log(err);
    sftp.end();
    cb(err);
  });
};

或者用simple-scp(轻量scp实现)

如果只想用scp协议,这个库也比scp2靠谱,配置更简洁。

3. 排查远程服务器的环境

  • 确认远程服务器的/opt/目录有足够的写入权限,磁盘空间也充足。虽然磁盘满了通常会报错,但偶尔也会出现只写入部分内容的情况,不妨检查一下。

4. 用原生scp命令验证

先手动在终端执行原生scp命令复制文件,看看是否能完整传输:

scp 你的文件名 root@10.20.138.185:/opt/

如果手动复制没问题,那百分百是scp2的问题,直接换库就好。

内容的提问来源于stack exchange,提问作者niku

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:11:38