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
相关产品推荐
相关产品推荐

