当前位置:首页>Linux>Node脚本向Linux服务推送文件

Node脚本向Linux服务推送文件

  • 2026-09-03 23:18:11
Node脚本向Linux服务推送文件
const fs = require('fs');const path = require('path');const { Client } = require('ssh2');const process = require('process');// 命令行参数解析function parseArgs() {  const options = {    host: 'ip_address',    port: 22,    username: 'username',    password: 'password',    local: '[local_file]',    remote: 'target_dir'  };  return options;}// 执行远程Linux命令function executeCommand(conn, command) {  return new Promise((resolve, reject) => {    console.log(`开始执行命令: ${command}`);    conn.exec(command, (err, stream) => {      if (err) {        console.error(`执行命令失败: ${err}`);        reject(err);        return;      }      let stdout = '';      let stderr = '';      // 捕获标准输出      stream.on('data', (data) => {        stdout += data.toString();        process.stdout.write(data);      });      // 捕获标准错误      stream.stderr.on('data', (data) => {        stderr += data.toString();        process.stderr.write(data);      });      // 处理命令完成      stream.on('close', (code, signal) => {        console.log(`命令执行完成,退出码: ${code}`);        if (code === 0) {          resolve(stdout);        } else {          reject(new Error(`命令执行失败,退出码: ${code}\n错误信息: ${stderr}`));        }      });      // 处理错误      stream.on('error', (err) => {        console.error(`命令执行错误: ${err}`);        reject(err);      });    });  });}// 推送单个文件function pushFile(conn, localFile, remoteDir) {  return new Promise((resolve, reject) => {    const fileName = path.basename(localFile);    const remoteFile = path.posix.join(remoteDir, fileName);    console.log(`开始传输: ${localFile} -> ${remoteFile}`);    // 获取文件大小    let fileSize = 0;    let transferred = 0;    try {      const stats = fs.statSync(localFile);      fileSize = stats.size;      console.log(`文件大小: ${(fileSize / 1024 / 1024).toFixed(2)} MB`);    } catch (err) {      console.error(`获取文件大小失败: ${err}`);      reject(err);      return;    }    // 使用ssh2的SFTP功能来传输文件    conn.sftp((err, sftp) => {      if (err) {        console.error(`SFTP初始化失败: ${err}`);        reject(err);        return;      }      // 读取本地文件并写入远程文件      const readStream = fs.createReadStream(localFile);      const writeStream = sftp.createWriteStream(remoteFile);      // 监听数据传输进度      readStream.on('data', (chunk) => {        transferred += chunk.length;        const progress = (transferred / fileSize * 100).toFixed(1);        console.log(progress);        const transferredMB = (transferred / 1024 / 1024).toFixed(2);        // 兼容 Windows PowerShell 的进度显示        try {          if (process.stdout.clearLine && process.stdout.cursorTo) {            // 支持 ANSI 转义序列的终端            process.stdout.clearLine();            process.stdout.cursorTo(0);            process.stdout.write(`传输进度: ${progress}% (${transferredMB} MB)`);          } else {            // 不支持的终端,使用简单的方式            if (progress === '100.0') {              console.log(`传输进度: ${progress}% (${transferredMB} MB)`);            }          }        } catch (error) {          // 忽略进度显示错误,确保文件传输继续          if (progress === '100.0') {            console.log(`传输进度: ${progress}% (${transferredMB} MB)`);          }        }      });      // 处理错误      readStream.on('error', (err) => {        console.error(`\n读取本地文件失败: ${err}`);        sftp.end();        reject(err);      });      writeStream.on('error', (err) => {        console.error(`\n写入远程文件失败: ${err}`);        sftp.end();        reject(err);      });      // 处理完成      writeStream.on('close', () => {        console.log(`\n传输成功: ${localFile}`);        sftp.end();        resolve();      });      // 开始传输      readStream.pipe(writeStream);    });  });}// 主函数async function main() {  const options = parseArgs();  // 创建SSH客户端  const conn = new Client();  return new Promise((resolve, reject) => {    conn.on('ready', async () => {      console.log('SSH连接成功');      try {        // 执行命令查看根目录内容        // 逐个传输文件        for (const file of options.local) {          await pushFile(conn, file, options.remote);        }        console.log('文件传输完成,开始解压');        await executeCommand(conn, `cd  ${options.remote} && unzip -o ${path.basename(options.local[0])} && ls`);        console.log('解压成功');        resolve();      } catch (err) {        reject(err);      } finally {        console.log('SSH连接已关闭');        conn.end();      }    }).on('error', (err) => {      console.error('SSH连接失败:', err);      reject(err);    }).connect({      host: options.host,      port: options.port,      username: options.username,      password: options.password    });  });}// 运行主函数main().catch((err) => {  console.error('执行失败:', err);  process.exit(1);});

最新文章

随机文章