java操作linux

news2024/11/26 3:43:59

文章目录

  • 远程连接服务器
  • 执行linux命令或shell脚本
    • 介绍
      • Process的方法
      • 相关类UML
    • 工具类
      • 基本工具类
      • 依赖第三方的工具类

远程连接服务器

java程序远程linux服务器有两个框架分别是:jsch与ganymed-ssh2框架。推荐使用jsch框架,因为ganymed-ssh2框架不支持麒麟服务器的连接,原因是openssl版本过高,ganymed-ssh框架不维护了所以不支持。

import cn.hutool.core.text.StrSplitter;
import cn.hutool.core.util.StrUtil;
import com.jcraft.jsch.*;

import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Properties;

/**
 * 远程连接linux服务并执行命令
 * 网上查询经过验证可以使用
 <dependency>
 <groupId>cn.hutool</groupId>
 <artifactId>hutool-all</artifactId>
 <version>5.7.21</version>
 </dependency>
 <dependency>
 <groupId>com.jcraft</groupId>
 <artifactId>jsch</artifactId>
 <version>0.1.55</version>
 </dependency>
 */
public class ShellUtils {

    private static Session session;

    private ShellUtils() {}

    public static ShellUtils getInstance() {
        return new ShellUtils();
    }

    /**
     * 初始化
     * @throws JSchException JSch异常
     */
    public void init(String ip, Integer port, String username,
                     String password) throws JSchException {
        JSch jsch = new JSch();
        jsch.getSession(username, ip, port);
        session = jsch.getSession(username, ip, port);
        session.setPassword(password);
        Properties sshConfig = new Properties();
        sshConfig.put("StrictHostKeyChecking", "no");
        session.setConfig(sshConfig);
        session.connect(1200 * 1000);
    }

    // 执行一条命令
    public String execCmd(String command) throws Exception {
        // 打开执行shell指令的通道
        Channel channel = session.openChannel("exec");
        ChannelExec channelExec = (ChannelExec) channel;
        String cmd = "source /etc/profile && source ~/.bash_profile " +
                "&& source ~/.bashrc &&  adb devices";
        channelExec.setCommand(cmd);
        channelExec.setCommand(command);
        channel.setInputStream(null);
        channelExec.setErrStream(System.err);
        // channel.setXForwarding();
        channel.connect();
        StringBuilder sb = new StringBuilder(16);
        try (InputStream in = channelExec.getInputStream();
             InputStreamReader isr = new InputStreamReader(in,
                     StandardCharsets.UTF_8);
             BufferedReader reader = new BufferedReader(isr)) {
            String buffer;
            while ((buffer = reader.readLine()) != null) {
                sb.append(buffer);
            }
        } finally {
            if (channelExec != null && channelExec.isConnected()) {
                channelExec.disconnect();
            }
            if (channel != null && channel.isConnected()) {
                channel.disconnect();
            }
        }
        return sb.toString();
    }

    // 执行一条命令 获取错误流中的内容
    public String execCmdErrContent(String command) throws Exception {
        // 打开执行shell指令的通道
        Channel channel = session.openChannel("exec");
        ChannelExec channelExec = (ChannelExec) channel;
        channelExec.setCommand(command);
        channel.setInputStream(null);
        ByteArrayOutputStream err = new ByteArrayOutputStream();
        channelExec.setErrStream(err);
        channel.connect();
        StringBuilder sb = new StringBuilder(16);
        try (InputStream in = channelExec.getErrStream();
             InputStreamReader isr = new InputStreamReader(in,
                     StandardCharsets.UTF_8);
             BufferedReader reader = new BufferedReader(isr)) {
            String buffer;
            while ((buffer = reader.readLine()) != null) {
                sb.append("\n").append(buffer);
            }
            if (StrUtil.contains(sb.toString(), "没有那个文件或目录")) {
                return "";
            } else {
                return sb.toString();
            }

        } finally {
            if (channelExec != null && channelExec.isConnected()) {
                channelExec.disconnect();
            }
            if (channel != null && channel.isConnected()) {
                channel.disconnect();
            }
        }
    }

    public static void closeConnect() {
        if (session != null && session.isConnected()) {
            session.disconnect();
        }
    }

    public static void main(String[] args) {
        ShellUtils instance = ShellUtils.getInstance();
        try {
            instance.init("192.168.81.122", 22, "root", "test1");
            String cmd = "ps -ef | grep monitor-0.0.1-SNAPSHOT.jar " +
                    "| grep -v xjar|grep -v grep | awk '{print $2}'";
            String ls = instance.execCmd(cmd);
//            String cmd = "cat /opt/dmdbms/log/dm_DW1_01B_202203.log " +
//                    "| grep -v 'INFO'";
//            String ls = instance.execCmd(cmd);
//            List<String> lineFreedList = StrSplitter.splitByRegex(
//                    StrUtil.trimToEmpty(ls),
//                    "\n", -1, true, true
//            );
//            for (String s : lineFreedList) {
//                List<String> stringList = StrSplitter.split(
//                        StrUtil.trimToEmpty(s),
//                        "=", -1, true, true
//                );
//                System.out.println(stringList);
//            }
            System.out.println(ls);
//            // 计算内存使用率(已使用内存/总内存)
//            String cmd1 = "free | sed -n '2p'";
//            String freeStr = instance.execCmd(cmd1);
//            List<String> freeInfoList = StrSplitter.splitByRegex(
//                    StrUtil.trimToEmpty(freeStr),
//                    "\\s+", -1, true, true
//            );
//            String allMemory = freeInfoList.get(1);
//            String usedMemory = freeInfoList.get(2);
//            double f1 = new BigDecimal(
//                    Float.valueOf(usedMemory) / Float.valueOf(allMemory)
//            )
//                    .setScale(2, BigDecimal.ROUND_HALF_UP)
//                    .doubleValue() * 100;
//            System.out.println(ls);
        } catch (Exception e) {
            System.out.println("error info");
            e.printStackTrace();
        } finally {
            ShellUtils.closeConnect();
        }
    }
}

执行linux命令或shell脚本

在Java中,调用runtime线程执行脚本是非常消耗资源的,所以切记不要频繁使用!
在调用runtime去执行脚本的时候,其实就是JVM开了一个子线程去调用JVM所在系统的命令,其中开了三个通道:输入流、输出流、错误流,其中输出流就是子线程走调用的通道。
大家都知道,waitFor是等待子线程执行命令结束后才访问,但是在runtime中,打开程序的命令如果不关闭,就不算子线程结束,比如如下代码。

private static Process p = null;
p = Runtime.getRuntime().exec("notepad.exe");
p.waitFor();
System.out.println("---------------我被执行了");

以上代码中,打开windows中记事本,如果我们不手动关闭记事本,那么输出语句就不会执行,这点是需要理解的。

介绍

// 在单独的进程中执行指定的字符串命令
public Process exec(String command)
// 在单独的进程中执行指定命令和变量
public Process exec(String[] cmdArray)
// 在指定环境的独立进程中执行指定命令和变量
public Process exec(String command,String[] envp)
// 在指定环境的独立进程中执行指定命令和变量
public Process exec(String[] cmdArray,String[] envp)
// 在有指定的环境和工作目录的独立进程中执行指定的字符串命令
public Process exec(String command,String[] encp,File dir)
// 在指定环境和工作目录的独立进程中执行指定的命令和变量
public Process exec(String[] cmdarray,String[] envp,File dir)
  • cmdArray: 包含所调用命令及其参数的数组。
    • 如果把命令放到一个String[]中时,必须把命令中每个部分作为一个元素存在String[]中,或者是把命令按照空格符分割得到的String[]。
//right
String[] cmdArray = {"tar", "-cf", tarName, fileName};
//error
String[] cmdArray = {"tar -cf", tarName, fileName};
  • command: 一条指定的系统命令。
  • envp: 字符串数组,其中每个元素的环境变量的设置格式为name=value;如果子进程应该继承当前进程的环境,则该参数为 null。
    • 模拟环境变量
val=2
call=Bash Shell
  • 测试shell脚本
#!/usr/bin/env bash
 
args=1
if [ $# -eq 1 ];then
  args=$1
  echo "The argument is: $args"
fi
 
echo "This is a $call"
start=`date +%s`
sleep 3s
end=`date +%s`
cost=$((($end - $start) * $args * $val))
echo "Cost Time: $cost"
  • 调用
String cmd = "sh " + script + " " + args;
String[] evnp = {"val=2", "call=Bash Shell"};
process = Runtime.getRuntime().exec(cmd, evnp);
BufferedReader input = new BufferedReader(
    new InputStreamReader(process.getInputStream())
);
String line = "";
while ((line = input.readLine()) != null) {
  System.out.println(line);
}
input.close();
  • 返回结果
/root/experiment/
The argument is: 4
This is a Bash Shell
Cost Time: 24
  • dir: 子进程的工作目录;如果子进程应该继承当前进程的工作目录,则该参数为 null。

Process的方法

  • destroy():杀掉子进程
  • exitValue():返回子进程的出口值,值0表示正常终止
  • getErrorStream():获取子进程的错误流
  • getInputStream():获取子进程的输入流
  • getOutputStream():获取子进程的输出流
  • waitFor():导致当前线程等待,如有必要,一直要等到由该Process对象表示的进程已经终止。如果已终止该子进程,此方法立即返回。如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程,0表示正常终止。

相关类UML

java.lang.Runtime
在这里插入图片描述
java.lang.Process
在这里插入图片描述

工具类

基本工具类

package utils;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ShellUtils {

    //执行shell命令并获取输出结果
    public static String execAndResult(String cmd){
        System.out.println("cmd: " + cmd);
        String result = "";
        try {
            Runtime runtime = Runtime.getRuntime();
            Process ps = runtime.exec(cmd);
            //获取执行结果的输入
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(ps.getInputStream())
            );
            StringBuffer sb = new StringBuffer();
            String line;
            while ((line = br.readLine()) != null) {
                //执行结果加上回车
                sb.append(line);
            }
            result = sb.toString();
            br.close();
            System.out.println("waitFor:" + ps.waitFor());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static void main(String[] args) {
        //执行普通命令
        execAndResult("shutdown -r");
        //执行脚本
        execAndResult("sh /data/jqxt/script/bak_pz.sh");
    }
}

依赖第三方的工具类

import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 <dependency>
 <groupId>cn.hutool</groupId>
 <artifactId>hutool-all</artifactId>
 <version>5.7.21</version>
 </dependency>
 */
public class MyRuntimeUtil {

    /**
     * 执行系统命令,使用系统默认编码
     *
     * @param cmds 命令列表,每个元素代表一条命令
     * @return 执行结果
     * @throws IORuntimeException IO异常
     */
    public static String execForStr(String... cmds)
            throws IORuntimeException {
        return execForStr(CharsetUtil.systemCharset(), cmds);
    }

    /**
     * 执行系统命令,使用系统默认编码
     *
     * @param charset 编码
     * @param cmds    命令列表,每个元素代表一条命令
     * @return 执行结果
     * @throws IORuntimeException IO异常
     * @since 3.1.2
     */
    public static String execForStr(Charset charset, String... cmds)
            throws IORuntimeException {
        return getResult(exec(cmds), charset);
    }

    public static String execForErrStr(Charset charset, String cmd)
            throws IORuntimeException {
        return getResultErr(exec(cmd), charset);
    }


    /**
     * 执行系统命令,使用系统默认编码
     */
    public static String execForStr(Charset charset, String cmds)
            throws IORuntimeException {
        return getResult(exec(cmds), charset);
    }

    /**
     * 执行系统命令,使用系统默认编码
     *
     * @param cmds 命令列表,每个元素代表一条命令
     * @return 执行结果,按行区分
     * @throws IORuntimeException IO异常
     */
    public static List<String> execForLines(String... cmds)
            throws IORuntimeException {
        return execForLines(CharsetUtil.systemCharset(), cmds);
    }

    /**
     * 执行系统命令,使用系统默认编码
     *
     * @param charset 编码
     * @param cmds    命令列表,每个元素代表一条命令
     * @return 执行结果,按行区分
     * @throws IORuntimeException IO异常
     * @since 3.1.2
     */
    public static List<String> execForLines(Charset charset, String... cmds)
            throws IORuntimeException {
        return getResultLines(exec(cmds), charset);
    }

    /**
     * 执行命令<br>
     * 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入
     *
     * @param cmds 命令
     * @return {@link Process}
     */
    public static Process exec(String... cmds) {
        Process process;
        try {
            process = new ProcessBuilder(handleCmds(cmds))
                    .redirectErrorStream(true)
                    .start();
        } catch (IOException e) {
            throw new IORuntimeException(e);
        }
        return process;
    }

    /**
     * 执行命令<br>
     * 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入
     *
     * @param cmd 命令
     * @return {@link Process}
     */
    public static Process exec(String cmd) {
        Process process;
        try {
            // 得到Java进程的相关Runtime运行对象
            Runtime runtime = Runtime.getRuntime();
            if (cmd.indexOf("|") > 0) {
                String[] cmdArr = {"sh", "-c", cmd};
                process = runtime.exec(cmdArr);
            } else {
                process = runtime.exec(cmd);
            }
        } catch (IOException e) {
            throw new IORuntimeException(e);
        }
        return process;
    }


    /**
     * 执行命令<br>
     * 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入
     *
     * @param envp 环境变量参数,传入形式为key=value,null表示继承系统环境变量
     * @param cmds 命令
     * @return {@link Process}
     * @since 4.1.6
     */
    public static Process exec(String[] envp, String... cmds) {
        return exec(envp, null, cmds);
    }

    /**
     * 执行命令<br>
     * 命令带参数时参数可作为其中一个参数,也可以将命令和参数组合为一个字符串传入
     *
     * @param envp 环境变量参数,传入形式为key=value,null表示继承系统环境变量
     * @param dir  执行命令所在目录(用于相对路径命令执行),null表示使用当前进程执行的目录
     * @param cmds 命令
     * @return {@link Process}
     * @since 4.1.6
     */
    public static Process exec(String[] envp, File dir, String... cmds) {
        try {
            return Runtime.getRuntime().exec(handleCmds(cmds), envp, dir);
        } catch (IOException e) {
            throw new IORuntimeException(e);
        }
    }

    // ------------------------------------ result

    /**
     * 获取命令执行结果,使用系统默认编码,获取后销毁进程
     *
     * @param process {@link Process} 进程
     * @return 命令执行结果列表
     */
    public static List<String> getResultLines(Process process) {
        return getResultLines(process, CharsetUtil.systemCharset());
    }

    /**
     * 获取命令执行结果,使用系统默认编码,获取后销毁进程
     *
     * @param process {@link Process} 进程
     * @param charset 编码
     * @return 命令执行结果列表
     * @since 3.1.2
     */
    public static List<String> getResultLines(Process process, Charset charset) {
        InputStream in = null;
        try {
            in = process.getInputStream();
            return IoUtil.readLines(in, charset, new ArrayList<>());
        } finally {
            IoUtil.close(in);
            destroy(process);
        }
    }

    /**
     * 获取命令执行结果,使用系统默认编码,,获取后销毁进程
     *
     * @param process {@link Process} 进程
     * @return 命令执行结果列表
     * @since 3.1.2
     */
    public static String getResult(Process process) {
        return getResult(process, CharsetUtil.systemCharset());
    }

    /**
     * 获取命令执行结果,获取后销毁进程
     *
     * @param process {@link Process} 进程
     * @param charset 编码
     * @return 命令执行结果列表
     * @since 3.1.2
     */
    public static String getResult(Process process, Charset charset) {
        InputStream in = null;
        InputStream errorStream = null;
        try {
            in = process.getInputStream();
            errorStream = process.getErrorStream();
            String errorResult = IoUtil.read(errorStream, charset);
            if (StrUtil.isNotBlank(errorResult)) {
                StaticLog.warn("Shell command execution error, because {}", errorResult);
            }
            return IoUtil.read(in, charset);
        } finally {
            IoUtil.close(in);
            IoUtil.close(errorStream);
            destroy(process);
        }
    }

    /**
     * 获取错误的执行结果,获取后销毁进程
     *
     * @param process {@link Process} 进程
     * @param charset 编码
     * @return 命令执行结果列表
     * @since 3.1.2
     */
    public static String getResultErr(Process process, Charset charset) {
        InputStream in = null;
        InputStream errorStream = null;
        try {
            in = process.getInputStream();
            errorStream = process.getErrorStream();
            // System.out.println("252"+IoUtil.read(errorStream, charset));
            return IoUtil.read(errorStream, charset);
        } finally {
            IoUtil.close(in);
            IoUtil.close(errorStream);
            destroy(process);
        }
    }


    /**
     * 获取命令执行异常结果,使用系统默认编码,,获取后销毁进程
     *
     * @param process {@link Process} 进程
     * @return 命令执行结果列表
     * @since 4.1.21
     */
    public static String getErrorResult(Process process) {
        return getErrorResult(process, CharsetUtil.systemCharset());
    }

    /**
     * 获取命令执行异常结果,获取后销毁进程
     *
     * @param process {@link Process} 进程
     * @param charset 编码
     * @return 命令执行结果列表
     * @since 4.1.21
     */
    public static String getErrorResult(Process process, Charset charset) {
        InputStream in = null;
        try {
            in = process.getErrorStream();
            return IoUtil.read(in, charset);
        } finally {
            IoUtil.close(in);
            destroy(process);
        }
    }

    /**
     * 销毁进程
     *
     * @param process 进程
     * @since 3.1.2
     */
    public static void destroy(Process process) {
        if (null != process) {
            process.destroy();
        }
    }

    /**
     * 增加一个JVM关闭后的钩子,用于在JVM关闭时执行某些操作
     *
     * @param hook 钩子
     * @since 4.0.5
     */
    public static void addShutdownHook(Runnable hook) {
        Runtime.getRuntime()
                .addShutdownHook(
                        (hook instanceof Thread) ?
                                (Thread) hook :
                                new Thread(hook)
                );
    }

    /**
     * 获得JVM可用的处理器数量(一般为CPU核心数)
     *
     * @return 可用的处理器数量
     * @since 5.3.0
     */
    public static int getProcessorCount() {
        return Runtime.getRuntime().availableProcessors();
    }

    /**
     * 获得JVM中剩余的内存数,单位byte
     *
     * @return JVM中剩余的内存数,单位byte
     * @since 5.3.0
     */
    public static long getFreeMemory() {
        return Runtime.getRuntime().freeMemory();
    }

    /**
     * 获得JVM已经从系统中获取到的总共的内存数,单位byte
     *
     * @return JVM中剩余的内存数,单位byte
     * @since 5.3.0
     */
    public static long getTotalMemory() {
        return Runtime.getRuntime().totalMemory();
    }

    /**
     * 获得JVM中可以从系统中获取的最大的内存数,单位byte,以-Xmx参数为准
     *
     * @return JVM中剩余的内存数,单位byte
     * @since 5.3.0
     */
    public static long getMaxMemory() {
        return Runtime.getRuntime().maxMemory();
    }

    /**
     * 获得JVM最大可用内存,计算方法为:<br>
     * 最大内存-总内存+剩余内存
     *
     * @return 最大可用内存
     */
    public static long getUsableMemory() {
        return getMaxMemory() - getTotalMemory() + getFreeMemory();
    }

    /**
     * 获取当前进程ID,首先获取进程名称,读取@前的ID值,如果不存在,则读取进程名的hash值
     *
     * @return 进程ID
     * @throws UtilException 进程名称为空
     * @since 5.7.3
     */
    public static int getPid() throws UtilException {
        final String processName = ManagementFactory.getRuntimeMXBean()
                .getName();
        if (StrUtil.isBlank(processName)) {
            throw new UtilException("Process name is blank!");
        }
        final int atIndex = processName.indexOf('@');
        if (atIndex > 0) {
            return Integer.parseInt(processName.substring(0, atIndex));
        } else {
            return processName.hashCode();
        }
    }

    /**
     * 处理命令,多行命令原样返回,单行命令拆分处理
     *
     * @param cmds 命令
     * @return 处理后的命令
     */
    private static String[] handleCmds(String... cmds) {
        if (ArrayUtil.isEmpty(cmds)) {
            throw new NullPointerException("Command is empty !");
        }

        // 单条命令的情况
        if (1 == cmds.length) {
            final String cmd = cmds[0];
            if (StrUtil.isBlank(cmd)) {
                throw new NullPointerException("Command is blank !");
            }
            cmds = cmdSplit(cmd);
        }
        return cmds;
    }

    /**
     * 命令分割,使用空格分割,考虑双引号和单引号的情况
     *
     * @param cmd 命令,如 git commit -m 'test commit'
     * @return 分割后的命令
     */
    private static String[] cmdSplit(String cmd) {
        final List<String> cmds = new ArrayList<>();

        final int length = cmd.length();
        final Stack<Character> stack = new Stack<>();
        boolean inWrap = false;
        final StrBuilder cache = StrUtil.strBuilder();

        char c;
        for (int i = 0; i < length; i++) {
            c = cmd.charAt(i);
            switch (c) {
                case CharUtil.SINGLE_QUOTE:
                case CharUtil.DOUBLE_QUOTES:
                    if (inWrap) {
                        if (c == stack.peek()) {
                            //结束包装
                            stack.pop();
                            inWrap = false;
                        }
                        cache.append(c);
                    } else {
                        stack.push(c);
                        cache.append(c);
                        inWrap = true;
                    }
                    break;
                case CharUtil.SPACE:
                    if (inWrap) {
                        // 处于包装内
                        cache.append(c);
                    } else {
                        cmds.add(cache.toString());
                        cache.reset();
                    }
                    break;
                default:
                    cache.append(c);
                    break;
            }
        }
        if (cache.hasContent()) {
            cmds.add(cache.toString());
        }
        return cmds.toArray(new String[0]);
    }
}

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

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

相关文章

诚邀莅临!道合顺将携“气体传感器”亮相深圳国际传感器与应用技术展览会

2024年4月14日-16日&#xff0c;深圳国际传感器与应用技术展览会将在深圳会展中心&#xff08;福田&#xff09;盛大举办。道合顺传感将携旗下系列专业气体传感器产品亮相展会&#xff0c;更有重磅新品传感器方案现场展示&#xff0c;真诚期待您的到来&#xff01; 传感器技术、…

球球大作战Python单机版本

球球大作战是一个多人在线游戏&#xff0c;玩家需要控制一个小球&#xff0c;通过吞食地图上的小点来增加自己的体积&#xff0c;同时避免被其他更大的球体吞噬。下面是一个简化版的球球大作战游戏&#xff0c;使用Python语言和pygame库来实现。在这个简化版中&#xff0c;我们…

pycharm环境配置踩坑

一、新建目录 venv 二、创建本地解释器 3、配置国内镜像 1&#xff09;镜像源 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 华中理工大…

宠物医院管理系统

文章目录 宠物医院管理系统一、系统演示二、项目介绍三、12000字论文参考四、系统部分页面展示五、部分代码展示六、底部获取项目源码和万字论文参考&#xff08;9.9&#xffe5;带走&#xff09; 宠物医院管理系统 一、系统演示 宠物医院管理系统 二、项目介绍 语言&#xf…

HarmonyOS实战开发-使用OpenGL实现2D图形绘制和动画。

介绍 基于XComponent组件调用Native API来创建EGL/GLES环境&#xff0c;从而使用标准OpenGL ES进行图形渲染。本项目实现了两个示例&#xff1a; 使用OpenGL实现2D的图形绘制和动画&#xff1b;使用OpenGL实现了在主页面绘制两个立方体&#xff0c;光源可以在当前场景中移动&…

MySQL客户端安装并配置免密登录

最近在写脚本时需要向MySQL数据库中存储数据&#xff0c;且脚本运行的服务器与MySQL服务器不是同一台服务器&#xff0c;而且需要保证MySQL密码的安全性&#xff0c;不能在脚本中暴露&#xff0c;所以就需要在服务器上安装MySQL客户端&#xff0c;并配置免密登录。 一、虚拟机…

使用注意力机制的 LSTM 彻底改变时间序列预测

目录 一、说明二、LSTM 和注意力机制简介三、为什么要将 LSTM 与时间序列注意力相结合&#xff1f;四、模型架构训练与评估 五、验证六、计算指标七、结论 一、说明 在时间序列预测领域&#xff0c;对更准确、更高效的模型的追求始终存在。深度学习的应用为该领域的重大进步铺…

【golang】动态生成微信小程序二维码实战下:golang 生成 小程序二维码图片 并通过s3协议上传到对象存储桶 | 腾讯云 cos

项目背景 在自研的系统&#xff0c;需要实现类似草料二维码的功能 将我们自己的小程序&#xff0c;通过代码生成相想要的小程序二维码 代码已经上传到 Github 需要的朋友可以自取 https://github.com/ctra-wang/wechat-mini-qrcode 一、生成Qrcode并提交到对象存储 通过源生A…

中颖51芯片学习4. 可编程计数器阵列PCA0

中颖51芯片学习4. 可编程计数器阵列PCA0 一、PCA介绍1. PCA简介2. SH79F9476的PCA0特性3. PCA0 功能4. 时钟5. PCA0原理框图6. 工作方式 二、PCA0寄存器1. PCA0标志寄存器2. PCA使能寄存器3. PCA0方式寄存器4. P0CPMn PCA捕捉/比较寄存器5. P0FORCE强制输出控制寄存器6. PCA0计…

《极域多媒体教室互动管理系统软件》控制方法大全

前言及背景&#xff1a; 当我坐在电脑前&#xff0c;打开它&#xff0c;点开谷歌&#xff0c;刚刚想打开百度&#xff0c;突然闪出来了&#xff1a; 该网页已被阻止&#xff01;&#xff01;&#xff01; 正文&#xff1a; 1.极域控制原理&#xff1a; 好…

使用EZDML自动生成测试数据

项目场景: 项目开发时,新创建的表需要增加一部分测试数据用于简单的功能测试。 问题描述 无论使用代码还是使用plsql自带的数据生成工具都感觉有点麻烦,我只想点点点就能生成数据。 解决方案: 提示:这里填写该问题的具体解决方案: 使用 EZDML 可以方便的生成测试数据。…

吴恩达深度学习 (week1,2)

文章目录 1、神经网络监督学习2、深度学习兴起原因3、深度学习二元分类4、深度学习Logistic 回归5、Logistic 回归损失函数6、深度学习梯度下降法7、深度学习向量法8、Python 中的广播9、上述学习总结10、大作业实现:rocket::rocket:&#xff08;1&#xff09;训练初始数据&…

如何开始用 C++ 写一个光栅化渲染器?

光栅化渲染器是计算机图形学中最基础且广泛应用的一种渲染技术&#xff0c;它将三维模型转化为二维图像。下面我们将逐步介绍如何使用C语言从零开始构建一个简单的光栅化渲染器。 一、理解光栅化渲染原理 光栅化是一种将几何数据&#xff08;如点、线、三角形&#xff09;转换…

一文详解手机IP地址如何改变

在互联网时代&#xff0c;手机的IP地址扮演着至关重要的角色。它不仅是手机在网络中的标识&#xff0c;还关系到手机的网络连接、隐私保护以及访问权限等方面。然而&#xff0c;在某些情况下&#xff0c;我们可能需要改变手机的IP地址&#xff0c;以满足特定的需求或解决网络问…

8×8点阵数码管显示驱动/大电流数码管驱动IC-VK16K33C SOP20

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK16K33C 封装形式&#xff1a;SOP20 概述 VK16K33C是一种带按键扫描接口的数码管或点阵LED驱动控制专用芯片&#xff0c;内部集成有数据锁 存器、键盘扫描、LED 驱动模块等电路。数据通过I2C通讯接口与MCU通信。SE…

腾讯再次回归电商,视频号小店真的要起飞了?

大家好&#xff0c;我是电商小布。 在互联网快速发展的现状下&#xff0c;各个平台都开始加入到电商这一行。 就连之前在电商上栽过跟头的腾讯&#xff0c;都再次回归电商&#xff0c;推出了视频号小店这个项目。 视频号小店背靠着视频号平台&#xff0c;结合当前最热的电商…

数字中国_智慧公厕

在面向未来构建城市竞争新优势、推动城市治理现代化的进程中&#xff0c;推进城市智慧化发展、数字化转型显得尤为重要。作为一种新形态的信息化公共厕所&#xff0c;智慧公厕扮演着举足轻重的角色&#xff0c;对于智慧城市和智慧乡村的发展至关重要&#xff0c;也是城市信息化…

如何加密VM虚拟机

参考官方文档&#xff1a;加密虚拟机 (vmware.com) 选择该虚拟机&#xff0c;然后选择虚拟机 > 设置。在选项选项卡中&#xff0c;选择访问控制。单击加密。选择适当的加密类型。单击加密&#xff0c;键入加密密码&#xff0c;然后单击加密。 要获得虚拟机的访问权限&#…

C++ primer 第十八章

C语言的三大特性&#xff1a;异常处理、命名空间、多重继承。 1.异常处理 异常处理机制允许我们能够将问题的检测与解决过程分离开来。 1.1、抛出异常 在C语言中&#xff0c;我们通过抛出一条表达式来引发一个异常。 当执行一个throw时&#xff0c;程序的控制权从throw转移…

linux 开机自启动

方式1—依赖桌面启动&#xff0c;一般适用与UI相关程序 1、创建运行脚本&#xff0c;以管理员放方式运行&#xff0c;加入密码 vim runapp.sh #!/bin/bash cd /home/nvidia/test echo ‘passcode’ | sudo -S ./testapp 2、终端输入 gnome-session-properties 3、在com…