NodeJs执行Linux脚本

news2024/11/29 2:54:52
(我们活着不能与草木同腐,不能醉生梦死,枉度人生,要有所作为。——方志敏)

在这里插入图片描述

为什么需要使用NodeJs执行Linux脚本

  1. linux的sh脚本命令编写复杂,在不熟悉linux交互式命令的情况下,使用高级编程语言来执行是最明智的选择
  2. 高级语言的生态较为完善,可以使用各种现成的工具包来完成脚本执行,比如NodeJs的npm,Java的maven等
  3. linux命令较为复杂,通常需要专业的运维来执行各种复杂的命令操作,但使用高级语言则屏蔽了linux底层命令,直接使用高级语言封装好的工具包即可

NodeJs执行脚本命令

应用场景举例

比如以下场景,在传统k8s容器化服务的架构下,每次服务的发布都需要重新安装依赖,快则两三分钟,慢则十分钟甚至更久,在没有专业运维的情况下,我们可以使用NodeJs来执行命令脚本,在每次发布前,对比两个版本的package.json文件,如果不一致,则再安装依赖,否则直接跳过安装阶段,使用当前目录下的node_moodules进行发布,这样在最优的情况下,就能省去依赖安装的时间,极大的提升了服务发布速度

场景细则
上一个版本的node_modules/package.json哪里来的
  • 在不使用容器化的情况下,我们在构建的目标目录下把上一个版本的node_modules/package.json复制来即可
  • 使用容器化的情况下,我们可以直接使用docker镜像生成一个node_modules/package.json缓存,然后加入新版本的Dockerfile下,使用相同的工作目录就可以复用

代码示例

// 在本地环境有nodejs的情况下 直接使用node xx.js执行即可
// 使用nodejs内置破快的exec执行linux命令
const { exec } = require('child_process');
// 本地的新json
const newJson = require('./package.json');
// 从上一个版本中复制来的旧json
const oldJson = require('./old.package.json');

// 安装依赖方法
const installDependencies = async (isInstall) => {
    return new Promise((resolve) =>{
		// 如果不需要安装则打印信息并跳出
        if(!isInstall){
            process.stdout.write('no need to install dependencies \n');
			// 结束promise
            return resolve();
        }
		// 执行yarn安装依赖命令
        const yarn = exec('yarn');
		// 实时监听该命令输入的信息并打印
        yarn.stdout.on('data', (data) => {
            process.stdout.write(data);
        });
		// 实时监听该命令的结束指令并打印
        yarn.stdout.on('end', () => {
            process.stdout.write('dependencies install complete \n');
            return resolve();
        })
		// 实时监听该命令的关闭指定并打印
        yarn.stdout.on('close', () => {
            process.stdout.write('dependencies install close \n');
            return resolve();
        });
    });
};

// 编译打包命令
const buildDist = async ()=>{
    return new Promise((resolve) =>{
		// 执行打包命令
        const yarn = exec('yarn run build');
        yarn.stdout.on('data', (data) => {
            process.stdout.write(data);
        });
        yarn.stdout.on('end', () => {
            process.stdout.write('build complete \n');
            return resolve();
        })
        yarn.stdout.on('close', () => {
            process.stdout.write('build close \n');
            return resolve();
        });
    });
};

// 立即执行函数,对比新旧两个依赖是否相同,然后执行依赖安装和打包编译操作
(async () => {

    const oldPro = oldJson.dependencies;
    const oldDev = oldJson.devDependencies;
    const oldProKeys = Object.keys(oldPro);
    const oldDevKeys = Object.keys(oldDev);

    const newPro = newJson.dependencies;
    const newdDev = newJson.devDependencies;
    const newProKeys = Object.keys(newPro);
    const newDevKeys = Object.keys(newdDev);

    let isInstall = false;

	// 对比新旧package.json的dependencies
    const loopProDependencies = () => {
        if (isInstall) {
            return;
        }
        /**
     * 对比新旧两个版本的安装包,出现以下情况的,需要重新安装依赖包
     * 1. 新的依赖在旧依赖中不存在的
     * 2. 新的依赖和旧依赖中版本号不同的
     */
        for (let i = 0; i < newProKeys.length; i++) {
            const prokey = newProKeys[i];
            const proKeyVersion = newPro[prokey];

            const oldKey = oldProKeys.find((v) => v === prokey);
            if (!oldKey) {
                process.stdout.write(`${prokey} no found, need install dependencies \n`);
                isInstall = true;
                break;
            }
            const oldKeyVersion = oldPro[oldKey];
            const isSameVersion = oldKeyVersion === proKeyVersion;
            if (!isSameVersion) {
                process.stdout.write(`${prokey} version difference, old_version:${oldKeyVersion} new_version:${proKeyVersion} \n`);
                isInstall = true;
                break;
            }
        }
    }

	// 对比新旧package.json的devDependencies
    const loopDevProDependencies = () => {
        if (isInstall) {
            return;
        }
        /**
     * 对比新旧两个版本的开发环境安装包,出现以下情况的,需要重新安装依赖包
     * 1. 新的依赖在旧依赖中不存在的
     * 2. 新的依赖和旧依赖中版本号不同的
     */
        for (let i = 0; i < newDevKeys.length; i++) {
            const devKey = newDevKeys[i];
            const devKeyVersion = newdDev[devKey];
            const oldKey = oldDevKeys.find((v) => v === devKey);
            if (!oldKey) {
                process.stdout.write(`${devKey} no found, need install dependencies \n`);
                isInstall = true;
                break;
            }
            const oldKeyVersion = oldDev[oldKey];
            const isSameVersion = oldKeyVersion === devKeyVersion;
            if (!isSameVersion) {
                process.stdout.write(`${devKey} version difference, old_version:${oldKeyVersion} new_version:${devKeyVersion} \n`);
                isInstall = true;
                break;
            }
        }
    }

    loopProDependencies();
    loopDevProDependencies();

    await installDependencies(isInstall);
    await buildDist();
})();






本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/843533.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Source Insight和Keil中文乱码

1、问题原因 由于Source Insight和Keil中的中文编码方式的不同&#xff0c;导致Keil中添加的中文注释在Source Insight中乱码&#xff1b;在Source Insight中添加的中文注释在Keil中乱码。所以需要统一两者的编码方式。 Source Insight默认编码方式为UTF-8&#xff0c;Keil中一…

SolidWorks二次开发系列入门100篇之98、99-分割、保存零件中的实体

从这四张图&#xff0c;看了来这个保存实体和分割图标是一样的&#xff0c;可能只是选项不一样&#xff0c;所以这里一起写了&#xff0c;不浪费时间。 经过了几个小时的研究&#xff0c;没搞定。大哭 CreateSaveBodyFeature这个没有api例子&#xff0c;2021上有例子&#xff…

从小白到大神之路之学习运维第75天-------Harbor企业镜像仓库部署

第四阶段 时 间&#xff1a;2023年8月7日 参加人&#xff1a;全班人员 内 容&#xff1a; Harbor企业镜像仓库部署 目录 一、案例概述 二、什么是 Harbor &#xff08;一&#xff09;Harbor 的优势 &#xff08;二&#xff09;Harbor 架构构成 &#xff08;三&…

C++动态规划经典试题解析之打家劫舍系列

1.前言 力扣上有几道与打家劫舍相关的题目,算是学习动态规划时常被提及的经典试题,很有代表性,常在因内大大小小的社区内看到众人对此类问题的讨论。 学习最好的方式便是归纳总结、借鉴消化,基于这个目的,本文对此类问题也做了讲解,在一些优秀思想的基础上添加了个人观…

自然语言处理[信息抽取]:MDERank关键词提取方法及其预训练模型----基于嵌入的无监督 KPE 方法 MDERank

NLP专栏简介:数据增强、智能标注、意图识别算法|多分类算法、文本信息抽取、多模态信息抽取、可解释性分析、性能调优、模型压缩算法等 专栏详细介绍:NLP专栏简介:数据增强、智能标注、意图识别算法|多分类算法、文本信息抽取、多模态信息抽取、可解释性分析、性能调优、模型…

一百四十八、Kettle——Linux上安装的kettle8.2连接Hive3.1.2

一、目标 kettle8.2在Linux安装好后&#xff0c;需要与Hive3.1.2数据库建立连接 二、前提 &#xff08;一&#xff09;在Linux已经安装好kettle并可以启动kettle &#xff08;二&#xff09;版本&#xff1a;kettle8.2.0 Hive3.1.2 Hadoop3.1.3 &#xff08;三&#…

虹科分享 | 如何通过ntopng流量规则来监控网络流量

让我们假设您有一个网络&#xff0c;其中本地主机生成恒定数量的流量。你如何发现他们是否行为错误&#xff1f;碰巧&#xff0c;一些本地主机行为开始异常&#xff0c;与它们之前相比&#xff0c;有一个异常的流量(发送或接收)&#xff1a;您如何发现这些情况并通过警报报告它…

使用langchain与你自己的数据对话(五):聊天机器人

之前我已经完成了使用langchain与你自己的数据对话的前四篇博客&#xff0c;还没有阅读这四篇博客的朋友可以先阅读一下&#xff1a; 使用langchain与你自己的数据对话(一)&#xff1a;文档加载与切割使用langchain与你自己的数据对话(二)&#xff1a;向量存储与嵌入使用langc…

[Securinets CTF Quals 2023] Admin Service,ret2libc,One is enough

只作了3个pwn&#xff0c;第4个附件没下下来&#xff0c;第5个不会 Admin Service 这是个最简单的题&#xff0c;最后来弄出来。原来只是看过关于maps文件的&#xff0c;一直没什么印象。 题目一开始设置seccomp禁用execv等&#xff0c;看来是用ORW&#xff0c;然后建了个mm…

STM32 4G学习

硬件连接 ATK-IDM750C模块可直接与正点原子 MiniSTM32F103开发板板载的ATK模块接口&#xff08;ATK-MODULE&#xff09;进行连接。 功能说明 ATK-IDM750C是正点原子&#xff08;ALIENTEK&#xff09;团队开发的一款高性能4G Cat1 DTU产品&#xff0c;支持移动4G、联通4G和…

详细介绍golang中.()类型断言的使用方法

文章目录 一、什么是.()用法&#xff1f;二、.()的基本用法三、.()用法的高级应用3.1 nil类型的转换3.2 将函数作为参数传递 四、.()使用中的注意事项五、总结 Golang是一门非常流行的编程语言&#xff0c;在很多领域都有着广泛的应用。在开发过程中&#xff0c;很多时候我们需…

verxriscv中Fpu中的加法器add源码分析

一 加法器端口 case class AddInput() extends Bundle{val source = Source()val rs1, rs2 = FpuFloat(exponentSize = p.internalExponentSize, mantissaSize = p.internalMantissaSize+addExtraBits)val rd = p.rfAddress()val roundMode = FpuRoundMode()val format = p.wit…

华为harmonyos4.0鸿蒙4.0安装谷歌服务框架Play商店,解决从服务器检索信息时出错

8月4号华为手机发布了全新的harmonyos4.0鸿蒙4.0系统&#xff0c;很多人需要问还是不是支持谷歌服务框架&#xff1f;那么答案是肯定的&#xff0c;它和鸿蒙3是一样的&#xff0c;一样的操作&#xff0c;一样的支持安装谷歌服务框架&#xff0c;安装Google play商店。测试机型&…

【新】通达OA前台反序列化漏洞分析

0x01 前言 注&#xff1a;本文仅以安全研究为目的&#xff0c;分享对该漏洞的挖掘过程&#xff0c;文中涉及的所有漏洞均已报送给国家单位&#xff0c;请勿用做非法用途。 通达OA作为历史上出现漏洞较多的OA&#xff0c;在经过多轮的迭代之后已经很少前台的RCE漏洞了。一般来说…

python+requests+json 接口测试思路示例

实际项目中用python脚本实现接口测试的步骤&#xff1a; 1 发送请求&#xff0c;获取响应 》》2 提取响应里的数据&#xff0c;对数据进行必要的处理 》》3 断言响应数据是否与预期一致 以豆瓣接口为例&#xff0c;做一个简单的接口测试吧。使用到的知识涉及requests库&…

Vue3 第三节 计算属性,监视属性,生命周期

1.computed计算属性 2.watch监视函数 3.watchEffect函数 4.Vue的生命周期函数 一.computed计算属性 计算属性简写和完整写法 <template><h1>一个人的信息</h1>姓&#xff1a;<input type"text" v-model"person.firstName" />…

车载A2B总线AD2428主从模式调试问题汇总

一&#xff0c;简介 在实际A2B总线一主一从模式的调试过程中下载程序出现许多报错提示&#xff0c;本文将遇到的错误进行汇总记录&#xff0c;方便相关开发者进行参考。 二&#xff0c;错误现象 2.1 Cable Terminal Shorted to Ground 主机IIS&#xff08;TDM&#xff09;线…

Mir 2.14 正式发布,Ubuntu 使用的 Linux 显示服务器

Canonical 公司最近发布了 Mir 2.14&#xff0c;这是该项目的最新版本。 Mir 2.14 在 Wayland 方面通过 ext-session-lock-v1 协议增加了对屏幕锁定器 (screen lockers) 的支持&#xff0c;并最终支持 Wayland 拖放。此外还整合了渲染平台的实现&#xff0c;放弃了之前在 Raspb…

常见监控网络链路和网络设备的方法

网络监控主要包括网络链路监控和网络设备监控&#xff0c;通常系统运维人员会比较关注。 一、网络链路监控 网络链路监控主要包含三个部分&#xff0c;网络连通性、网络质量、网络流量。 连通性和质量的监控手段非常简单&#xff0c;就是在链路一侧部署探针&#xff0c;去探…

搭建 elasticsearch8.8.2 伪集群 windows

下载windows 版本 elasticsearch8.8.2 以下链接为es 历史版本下载地址&#xff1a; Past Releases of Elastic Stack Software | Elastic windows 单节点建立方案&#xff1a; 下载安装包 elasticsearch-8.8.2-windows-x86_64.zip https://artifacts.elastic.co/download…