当前位置: 首页 > news >正文

java:自定义变量加载到系统变量后替换shell模版并执行shell

这里的需求前提是,在项目中进行某些操作前,需要在命令后对shell配置文件的进行修改(如ip、port),这个对于用户是不友好的,需要改为用户页面输入ip、port,后台自动去操作修改配置;那么这篇博客的由来就有了。

在这里插入图片描述
上面图片是AI创作,未经允许,不可商用哦!

目录

  • 实现功能描述
  • 功能实现拆解
    • 项目加载自定义变量
      • 项目加载自定义变量文件到系统变量中
        • 自定义变量文件如下
        • java代码如下
        • 实操验证如下
      • shell通过source .env环境变量文件方式加载
        • test.env环境变量文件如下
        • shell模版文件如下
        • 实操验证如下
    • 替换shell模版并运行
      • 项目加载自定义变量文件到系统变量中
      • shell通过source .env环境变量文件方式加载

以下为实际工作简化后描述

实现功能描述

  1. 项目加载自定义变量
  2. 自定义变量替换shell模版内容
  3. 项目运行shell

功能实现拆解

针对上述功能描述,其实可以拆解为三步

  1. 实现项目加载自定义变量
  2. 实现替换shell模版内容
  3. 运行shell

项目加载自定义变量

这里有两种实现,
一种是项目加载自定义变量文件到系统变量中;
另一种是shell通过source .env环境变量方式加载。

项目加载自定义变量文件到系统变量中

这种方法的好处是项目中可以获取到自定义变量,如果项目代码需要获取自定义变量进行操作,可以考虑使用此方式

新增一个自定义变量文件(当然也可以在代码中固定写入变量直接加载到系统中,这样的缺点就是不灵活,如果有变动就需要改代码)

自定义变量文件如下

BASE_ROOT_DIR=/home
LICENSE_PATH=/home/LICENSE
PACKAGE_PATH=/home/test.tar.gz

java代码如下

    /*** 加载自定义变量文件到系统变量中* @param configFile*/public static void loadProperties(String configFile){try {FileInputStream propFile = new FileInputStream(configFile);Properties p = new Properties(System.getProperties());p.load(propFile);System.setProperties(p);} catch (Exception e) {e.printStackTrace();}}

调用loadProperties方法后,就可以通过System.getProperty("key")获取自定义的变量了
如获取BASE_ROOT_DIRSystem.getProperty("BASE_ROOT_DIR")

实操验证如下

自定义变量文件
在这里插入图片描述

测试代码

import java.io.FileInputStream;
import java.util.Properties;public class LoadProperties {public static void main(String[] args) {String configFile = "/Users/kunzhi/Downloads/learn/linuxTest/config.sh";loadProperties(configFile);System.out.println("BASE_ROOT_DIR: " + System.getProperty("BASE_ROOT_DIR"));System.out.println("LICENSE_PATH: " + System.getProperty("LICENSE_PATH"));System.out.println("PACKAGE_PATH: " + System.getProperty("PACKAGE_PATH"));}public static void loadProperties(String configFile){try {FileInputStream propFile = new FileInputStream(configFile);Properties p = new Properties(System.getProperties());p.load(propFile);System.setProperties(p);} catch (Exception e) {e.printStackTrace();}}
}

运行输出结果
在这里插入图片描述

shell通过source .env环境变量文件方式加载

这种方法的好处是在shell执行时直接获取环境变量,不需要项目代码做多余的操作

  1. 新增一个.env环境变量文件(如test.env)
  2. 当在执行的shell文件中首行加入source命令(source test.env)或者先在命令行执行命令source test.env后,执行shell文件

test.env环境变量文件如下

BASE_ROOT_DIR=/home
LICENSE_PATH=/home/LICENSE
PACKAGE_PATH=/home/test.tar.gz

shell模版文件如下

cd ${DATASYS_BASE_ROOT_DIR}
pwdecho "DATASYS_PACKAGE_PATH: ${DATASYS_PACKAGE_PATH}"
echo "PACKAGE_PATH: ${PACKAGE_PATH}"
echo "LICENSE_PATH: ${LICENSE_PATH}"

实操验证如下

创建shell模版文件 test.sh,并执行
在这里插入图片描述
创建环境变量文件 test.env,并在test.sh文件首行加入命令:source test.env
在这里插入图片描述

替换shell模版并运行

因为替换是否成功,只有通过运行结果才能有力证明,所以我们放在一起看

由于替换shell模版内容的具体操作受自定义变量加载方式影响,所以我们还是按照两种加载方式来看

项目加载自定义变量文件到系统变量中

如果是项目加载自定义变量文件到系统变量中,还需要项目获取变量并传入shell替换;

代码如下

import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Properties;public class LoadProperties {public static void main(String[] args) {String configFile = "/Users/kunzhi/Downloads/learn/linuxTest/config.sh";//加载自定义环境变量loadProperties(configFile);String BASE_ROOT_DIR = System.getProperty("BASE_ROOT_DIR");String LICENSE_PATH = System.getProperty("LICENSE_PATH");String PACKAGE_PATH = System.getProperty("PACKAGE_PATH");System.out.println(BASE_ROOT_DIR + ": " + System.getProperty("BASE_ROOT_DIR"));System.out.println(LICENSE_PATH + ": " + System.getProperty("LICENSE_PATH"));System.out.println(PACKAGE_PATH + ": " + System.getProperty("PACKAGE_PATH"));//需要传入shell模版替换的内容String[] evnp = {"BASE_ROOT_DIR=" + BASE_ROOT_DIR, "LICENSE_PATH=" + LICENSE_PATH, "PACKAGE_PATH=" + PACKAGE_PATH};String shellFile = "/Users/kunzhi/Downloads/learn/linuxTest/test1.sh";//替换并运行shellreplaceAndRun(shellFile, evnp);}//加载自定义环境变量public static void loadProperties(String configFile){try {FileInputStream propFile = new FileInputStream(configFile);Properties p = new Properties(System.getProperties());p.load(propFile);System.setProperties(p);} catch (Exception e) {e.printStackTrace();}}//替换并运行shellprivate static void replaceAndRun(String path, String[] evnp) {try {Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", path}, evnp,null);//只有process.waitFor() 结果为0,才说明执行成功了if (process.waitFor() != 0) {throw new Exception(String.valueOf(process.waitFor()));}InputStreamReader ir = new InputStreamReader(process.getInputStream());LineNumberReader input = new LineNumberReader(ir);String line;//输入shell中执行的每一行while ((line = input.readLine()) != null){if (line.contains("ERROR")) {throw new Exception("ERROR");}System.out.println(line);}} catch (Exception e) {System.out.println(e);}}
}

运行结果
在这里插入图片描述

shell通过source .env环境变量文件方式加载

如果是shell通过source .env环境变量方式加载,在上一步实操演示可以看出,其实已经达到替换效果,直接执行shell文件即可了

代码如下

package test;import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.Properties;/*** @author yanZhiHang* @date 2023/2/26 17:06*/
public class LoadProperties {public static void main(String[] args) {runShell(shellFile1);}private static void runShell(String path) {try {Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", path}, null,null);if (process.waitFor() != 0) {throw new Exception(String.valueOf(process.waitFor()));}InputStreamReader ir = new InputStreamReader(process.getInputStream());LineNumberReader input = new LineNumberReader(ir);String line;while ((line = input.readLine()) != null){if (line.contains("ERROR")) {throw new Exception("ERROR");}System.out.println(line);}} catch (Exception e) {System.out.println(e);}}
}

相关文章:

java:自定义变量加载到系统变量后替换shell模版并执行shell

这里的需求前提是,在项目中进行某些操作前,需要在命令后对shell配置文件的进行修改(如ip、port),这个对于用户是不友好的,需要改为用户页面输入ip、port,后台自动去操作修改配置;那么…...

Redis高级删除策略与数据淘汰

第二章:Redis高级 学习目标 目标1:能够说出redis中的数据删除策与略淘汰策略 目标2:能够说出主从复制的概念,工作流程以及场景问题及解决方案 目标3:能够说出哨兵的作用以及工作原理,以及如何启用哨兵 …...

社畜大学生的Python之pandas学习笔记,保姆入门级教学

接上期,上篇介绍了 NumPy,本篇介绍 pandas。 目录 pandas 入门pandas 的数据结构介绍基本功能汇总和计算描述统计处理缺失数据层次化索引 pandas 入门 Pandas 是基于 Numpy 构建的,让以 NumPy 为中心的应用变的更加简单。 Pandas是基于Numpy…...

20_FreeRTOS低功耗模式

目录 低功耗模式简介 STM32低功耗模式 Tickless模式详解 Tickless模式相关配置 实验源码 低功耗模式简介 很多应用场合对于功耗的要求很严格,比如可穿戴低功耗产品、物联网低功耗产品等。 一般MCU都有相应的低功耗模式,裸机开发时可以使用MCU的低功耗模式。 FreeRTOS也…...

Hive的使用方式

操作Hive可以在Shell命令行下操作,或者是使用JDBC代码的方式操作 针对命令行这种方式,其实还有两种使用 第一个是使用bin目录下的hive命令,这个是从hive一开始就支持的使用方式 后来又出现一个beeline命令,它是通过HiveServer2服…...

Flume三大核心组件

Flume的三大核心组件: Source:数据源 Channel:临时存储数据的管道 Sink:目的地 Source:数据源:通过source组件可以指定让Flume读取哪里的数据,然后将数据传递给后面的 channel Flume内置支持读…...

数据结构(六)二叉树

一、树形结构概念树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:1、有一个…...

Docker buildx 的跨平台编译

docker buildx 默认的 docker build 命令无法完成跨平台构建任务,我们需要为 docker 命令行安装 buildx 插件扩展其功能。buildx 能够使用由 Moby BuildKit 提供的构建镜像额外特性,它能够创建多个 builder 实例,在多个节点并行地执行构建任…...

【java基础】方法重载和方法重写

文章目录方法重载方法重写方法重载 方法重载就是可以在一个类里面定义多个相同名称的方法,只需要参数列表的个数或者类型不同就行。 public class Overload {public int add(int a, int b) {return a b;}public double add(double a, double b) {return a b;}}对…...

Gradle7.4安装与基本使用

文章目录一.前言二.下载Gradle三.Gradle镜像源-全局级配置四.配置Gradle wrapper-项目级配置五.Gradle对测试的支持五.生命周期5.1 settings文件六.Gradle任务入门6.1 任务行为6.2 任务依赖方式七. Dependencies依赖引入7.1 依赖冲突及解决方案八.Gradle整合多模块SpringBoot九…...

[系统安全] 虚拟化安全之虚拟化概述

本文为笔者从零基础学习系统安全相关内容的笔记,如果您对系统安全、逆向分析等内容感兴趣或者想要了解一些内容,欢迎关注。本系列文章将会随着笔者在未来三年的读研过程中持续更新,由于笔者现阶段还处于初学阶段,不可避免参照复现各类书籍内容,如书籍作者认为侵权请告知,…...

如何从零开始系统的学习项目管理?

经常会有人问,项目管理到底应该学习一些什么?学习考证之后能得到什么价值? 以下我就总结一下内容 一,学习项目管理有用吗? 有效的项目管理带来的益处大致包括以下几个方面:更有效达成业务目标、满足相关…...

面试题-----

面试题---- 一.HTML 1.常用哪些浏览器进行测试,对应有哪些内核? ①IE------------------->Trident ②Chrome---------->以前是Webkit现在是Blink ③Firefox------------>Gecko ④Safari-------------->Webkit ⑤Opera--------------&…...

线材-电子线载流能力

今天来讲的是关于电子线的一个小知识,可能只做板子的工程师遇到此方面的问题会比较少,做整机的工程师则必然会遇到此方面问题,那就是线材问题。 下面主要说下电子线的过电流能力。(文末有工具下载)电子线(h…...

单变量回归问题

单变量回归问题 对于某房价问题,x为房屋大小,h即为预估房价,模型公式为: hθ(x)θ0θ1xh_{\theta}(x)\theta_{0}\theta_{1}x hθ​(x)θ0​θ1​x 要利用训练集拟合该公式(主要是计算θ0、θ1\theta_{0}、\theta_{1}θ…...

ubuntu/linux系统知识(36)linux网卡命名规则

文章目录背景命名规范系统默认命名规则优势背景 很久以前Linux 操作系统的网卡设备的传统命名方式是 eth0、eth1、eth2等,属于biosdevname 命名规范。 服务器通常有多块网卡,有板载集成的,同时也有插在PCIe插槽的。Linux系统的命名原来是et…...

java的一些冷知识

接口并没有继承Object类首先接口是一种特殊的类,理由就是将其编译后是一个class文件大家都知道java类都继承自Object,但是接口其实是并没有继承Object类的 可以自己写代码测试: 获取接口类的class对象后遍历它的methods,可以发现是不存在Obje…...

java代理模式

代理模式 为什么要学习代理模式?因为这是SpringAOP的底层! 【SpringAOP和SpingMVC}】 代理模式的分类: 静态代理 动态代理 代理就像这里的中介,帮助你去做向房东租房,你不能直接解出房东,而房东和中介…...

JUC包:CountDownLatch源码+实例讲解

1 缘起 有一次听到同事谈及AQS时,我有很多点懵, 只知道入队和出队,CLH(Craig,Landin and Hagersten)锁,并不了解AQS的应用, 同时结合之前遇到的多线程等待应用场景,发现…...

Log4j2基本使用

文章目录1. Log4j2入门2. Log4j2配置3. Log4j2异步日志4. Log4j2的性能Apache Log4j 2是对Log4j的升级版,参考了logback的一些优秀的设计,并且修复了一些问题,因此带 来了一些重大的提升,主要有: 异常处理&#xff0c…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层&#xf…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...