最新封装见:http://blog.csdn.net/llmys/article/details/52997924
最近在做自动化测试的时候,需要用到nodejs ssh2模块将windows上的文件传到linux机器上,由于网上别人封装的ssh2-util模块实在不好用,不是下载文件夹之后无法退出,就是下载不下来。可能是我自己用法不对的缘故,由于我没有学过JS,很多不懂,所有用ssh2更加不好用,每次我都想说一句:"好恼火"。
好了,吐槽完毕,接下来写写我封装的基本功能。仅仅实现了运行linux的shell命令、上传文件、下载文件、上传文件夹、下载文件夹。
上传文件夹思路:首先获取本地机器文件目录下的子目录列表以及文件名列表,再通过调用shell函数执行mkdir命令在linux机器上面创建文件夹,然后再一个一个的上传文件。
下载文件夹思路:首先获取远程linux机器目录下的子目录列表以及文件名列表,再在本地机器上创建文件夹,再将文件一个一个的下载下来。
也许是我没有学过JS、Node.js的缘故,每次用同一个连接下来多个文件就会出问题,并发多了就出现问题了,希望会的人可以给我指点一下思路,或者给我说一下应该怎么使用。所有在我的代码中我都是等待ssh的操作一个一个的完成之后再去执行其他操作。
"use strict"
var ssh2 = require("ssh2");
var util=require("util")
var events=require("events");
var Client = require("ssh2").Client;
var fs = require("fs");
var path = require('path');
var async = require('async');
* 描述:连接远程电脑
* 参数:server 远程电脑凭证;then 回调函数
* 回调:then(conn) 连接远程的client对象
function Connect(server, then){
var conn = new Client();
conn.on("ready", function(){
then(conn);
}).on('error', function(err){
//console.log("connect error!");
}).on('end', function() {
//console.log("connect end!");
}).on('close', function(had_error){
//console.log("connect close");
}).connect(server);
* 描述:运行shell命令
* 参数:server 远程电脑凭证;cmd 执行的命令;then 回调函数
* 回调:then(err, data) : data 运行命令之后的返回数据信息
function Shell(server, cmd, then){
Connect(server, function(conn){
conn.shell(function(err, stream){
if(err){
then(err);
}else{// end of if
var buf = "";
stream.on('close', function(){
conn.end();
then(err, buf);
}).on('data', function(data){
buf=buf+data;
}).stderr.on('data', function(data) {
console.log('stderr: ' + data);
stream.end(cmd);
* 描述:上传文件
* 参数:server 远程电脑凭证;localPath 本地路径;remotePath 远程路径;then 回调函数
* 回调:then(err, result)
function UploadFile(server, localPath, remotePath , then){
Connect(server, function(conn){
conn.sftp(function(err, sftp){
if(err){
then(err);
}else{
sftp.fastPut(localPath, remotePath, function(err, result){
conn.end();
then(err, result);
* 描述:下载文件
* 参数:server 远程电脑凭证;remotePath 远程路径;localPath 本地路径;then 回调函数
* 回调:then(err, result)
function DownloadFile(server, remotePath, localPath, then){
Connect(server, function(conn){
conn.sftp(function(err, sftp){
if(err){
then(err);
}else{
sftp.fastGet(remotePath, localPath, function(err, result){
if(err){
then(err);
}else{
conn.end();
then(err, result);
* 描述:获取远程文件路径下文件列表信息
* 参数:server 远程电脑凭证;
* remotePath 远程路径;
* isFile 是否是获取文件,true获取文件信息,false获取目录信息;
* then 回调函数
* 回调:then(err, dirs) : dir, 获取的列表信息
function GetFileOrDirList(server, remotePath, isFile, then){
var cmd = "find " + remotePath + " -type "+ (isFile == true ? "f":"d") + "\r\nexit\r\n";
Shell(server, cmd, function(err, data){
var arr = [];
var remoteFile = [];
arr = data.split("\r\n");
arr.forEach(function(dir){
if(dir.indexOf(remotePath) ==0){
remoteFile.push(dir);
then(err, remoteFile);
* 描述:控制上传或者下载一个一个的执行
function Control(){
events.EventEmitter.call(this);
util.inherits(Control, events.EventEmitter); // 使这个类继承EventEmitter
var control = new Control();
control.on("donext", function(todos, then){
if(todos.length > 0){
var func = todos.shift();
func(function(err, result){
if(err){
throw err;
then(err);
}else{
control.emit("donext", todos, then);
}else{
then(null);
* 描述:下载目录到本地
* 参数:server 远程电脑凭证;
* remotePath 远程路径;
* localDir 本地路径,
* then 回调函数
* 回调:then(err)
function DownloadDir(server, remoteDir,localDir, then){
GetFileOrDirList(server, remoteDir, false, function(err, dirs){
if(err){
throw err;
}else{
GetFileOrDirList(server, remoteDir, true, function(err, files){
if(err){
throw err;
}else{
dirs.shift();
dirs.forEach(function(dir){
var tmpDir = path.join(localDir, dir.slice(remoteDir.length+1)).replace(/[//]\g/, '\\');
// 创建目录
fs.mkdirSync(tmpDir);
var todoFiles = [];
files.forEach(function(file){
var tmpPath = path.join(localDir, file.slice(remoteDir.length+1)).replace(/[//]\g/, '\\');
todoFiles.push(function(done){
DownloadFile(server, file, tmpPath, done);
console.log("downloading the "+file);
});// end of todoFiles.push
control.emit("donext", todoFiles, then);
* 描述:获取windows上的文件目录以及文件列表信息
* 参数:destDir 本地路径,
* dirs 目录列表
* files 文件列表
function GetFileAndDirList(localDir, dirs, files){
var dir = fs.readdirSync(localDir);
for(var i = 0; i < dir.length; i ++){
var p = path.join(localDir, dir[i]);
var stat = fs.statSync(p);
if(stat.isDirectory())
dirs.push(p);
GetFileAndDirList(p, dirs, files);
files.push(p);
* 描述:上传文件夹到远程目录
* 参数:server 远程电脑凭证;
* localDir 本地路径,
* remotePath 远程路径;
* then 回调函数
* 回调:then(err)
function UploadDir(server, localDir, remoteDir, then){
var dirs = [];
var files = [];
GetFileAndDirList(localDir, dirs, files);
// 创建远程目录
var todoDir = [];
dirs.forEach(function(dir){
todoDir.push(function(done){
var to = path.join(remoteDir, dir.slice(localDir.length+1)).replace(/[\\]/g, '/');
var cmd = "mkdir -p " + to +"\r\nexit\r\n";
console.log(cmd);
Shell(server, cmd, done);
})// end of push
// 上传文件
var todoFile = [];
files.forEach(function(file){
todoFile.push(function(done){
var to = path.join(remoteDir, file.slice(localDir.length+1)).replace(/[\\]/g, '/');
console.log("upload " + to);
UploadFile(server, file, to, done);
control.emit("donext", todoDir, function(err){
if(err){
throw err;
}else{
control.emit("donext", todoFile, then);
exports.Shell = Shell;
exports.UploadFile = UploadFile;
exports.DownloadFile = DownloadFile;
exports.GetFileOrDirList = GetFileOrDirList;
exports.DownloadDir = DownloadDir;
exports.UploadDir = UploadDir;
最近在做自动化测试的时候,需要用到nodejs ssh2模块将windows上的文件传到linux机器上,由于网上别人封装的ssh2-util模块实在不好用,不是下载文件夹之后无法退出,就是下载不下来。可能是我自己用法不对的缘故,由于我没有学过JS,很多不懂,所有用ssh2更加不好用,每次我都想说一句:"好恼火"。好了,吐槽完毕,接下来写写我封装的基本功能。仅仅实现了运行linux的shell
大厂技术高级前端Node进阶
点击上方程序员成长指北,关注公众号
回复1,加入高级Node交流群本文来自读者@凌览 投稿,欢迎大家投稿????????????????????????
原文链接:https://juejin.cn/post/71943401789393470001前言这是【Node.js实战】[1]专栏内的第6篇文章,专栏是分享使用Node.js技术编写实用脚本技巧。专栏现有文章:仿jsDoc写一个最...
由于最近在写一个自动测试的代码,用nodejs写,需要用ssh2模块将本地机器上的文件以及文件夹上传到远程的linux机器上,在百度上面看的相关的例子,但是上面的例子,如果一个连接下载一次然后关闭就不会出错,若同一个连接多次操作就会出现很大的问题。
百度上面百度到的例子如下:
conn.sftp(function(err, sftp){
if(err){
throw err;
1 //前台命令下发
2 app.get('/test/fileDownload', function (req, res) {
3 var downloadPath = req.query.downloadPath;
4 con...
让前端觉得如获神器的不是NodeJS能做网络编程,而是NodeJS能够操作文件。小至文件查找,大至代码编译,几乎没有一个前端工具不操作文件。换个角度讲,几乎也只需要一些数据处理逻辑,再加上一些文件操作,就能够编写出大多数前端工具。本章将介绍与之相关的NodeJS内置模块。
NodeJS提供了基本的文件操作API,但是像文件拷贝这种高级功能就没有提供,因此我们先拿文件拷贝程序练手...
-v10.16.0或更高版本节点v12.0.0或更高版本,以支持Ed25519键
(可选)将设置为可选的程序包依赖项(您不需要显式/独立于ssh2进行安装),将在可能的情况下自动生成并使用。 有关其自身的要求,请参见项目的文档。 该插件当前用于帮助生成最佳的默认密码列表
npm install ssh2
在服务器上执行“正常运行时间”
const { readFileSync } = require ( 'fs' ) ;
const { Client } = require ( 'ssh2' ) ;
const conn = new Client
Introduction
nodejs 脚本实现上传前端打包目录 dist。用到 ssh2-sftp-client 这个包实现上传功能。
在项目根目录运行 upload-dist 把打包后的 dist 目录上传到服务器
服务器上的 dist 目录内容会被清空后,再上传
Installation
1、首先执行 npm install 安装ssh2-sftp-client 、path、recursive-readdir 。ssh2-sftp-client是请求时使用的client,path用来读取路径,recursive-readdir读取本地执行的文件夹
let Client = require('ssh2-sftp-client');
let path = require(...
2. 然后,您需要使用fs.readdirSync()方法读取文件夹中的所有文件,可以使用以下代码:
const files = fs.readdirSync('文件夹路径');
3. 接下来,您需要使用fs.unlinkSync()方法删除每个文件的内容,可以使用以下代码:
files.forEach(file => {
fs.unlinkSync(`文件夹路径/${file}`);
4. 最后,您可以使用fs.rmdirSync()方法删除空文件夹,可以使用以下代码:
fs.rmdirSync('文件夹路径');
希望这个回答能够帮助您解决问题。