java 执行linux 命令

文章目录

  • 前言
  • 一、linux命令执行
  • 二、使用步骤
  • 三、踩坑

前言

java 执行linux 命令;
本文模拟复制linux文件到指定文件夹后打zip包后返回zip名称,提供给下载接口下载zip;

一、linux命令执行

linux命令执行Process process = Runtime.getRuntime().execProcess process = new ProcessBuilder(commands).start();

   /*** 执行Linux命令*/public static void execCommand(String commands) throws IOException {Process process = null;BufferedReader reader = null;try {//创建进程实例执行Linux命令process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", commands});// 获取标准输入流reader = new BufferedReader(new InputStreamReader(process.getInputStream()));String line;while ((line = reader.readLine()) != null) {//log.info("linux----" + line);}// 等待进程结束int exitCode = process.waitFor();if (exitCode != 0) {log.error("执行Linux命令异常,exitCode={},linux command={}", exitCode, commands);throw new BusinessCheckException("执行Linux命令异常");}} catch (IOException | InterruptedException e) {log.error("执行Linux命令异常", e);throw new BusinessCheckException("执行Linux命令异常");} finally {if (reader != null) {reader.close();}if (process != null) {process.destroy();}}}

二、使用步骤

  1. 通过linux命令,打包目标数据到zip
public String downToZip(CorpQrCodeReq req, HttpServletResponse response) {StopWatch sw = new StopWatch();// 参数校验if (CollectionUtils.isEmpty(req.getCorpIds()) || CollectionUtils.isEmpty(req.getCorpNames())) {return "0";}// 生成保存目录文件夹String uuid = UUID.randomUUID().toString().replace("-", "");String baseUploadPath = "/tmp/zip/"+uuid+"/";FileUtil.mkdir(baseUploadPath);try {//生成二维码到临时目录List<String> enterpriseIds = req.getCorpIds();List<String> enterpriseNames = req.getCorpNames();List<String> command = new ArrayList<>(enterpriseIds.size());// 拼接被复制的文件地址for (int i = 0; i < enterpriseIds.size(); i++) {String path = this.qrCode(CorpQrCodeReq.builder().corpIds(Lists.newArrayList(enterpriseIds.get(i))).corpNames(Lists.newArrayList(enterpriseNames.get(i))).build());command.add(path + " ");}sw.stop();log.info(sw.getLastTaskName() + sw.getTotalTimeSeconds() + "s");sw.start("执行cp命令");String property = System.getProperty("line.separator");//拼接shell脚本String sb = " for i in  " + String.join(" ", command) +property +"do" +property +" cp -n  \"$i\" " + baseUploadPath +property +"done";//执行cp命令execCommand(sb);sw.stop();log.info(sw.getLastTaskName() + sw.getTotalTimeSeconds() + "s");sw.start("执行压缩命令");//执行压缩命令 统一压缩比一个一个压缩进去效率高 //-j忽略源文件路径,直接打包目标文件String zipCommand = " /bin/zip -1 -j " + baseUploadPath.concat(".zip") + " " + baseUploadPath + "/*";execCommand(zipCommand);sw.stop();log.info(sw.getLastTaskName() + sw.getTotalTimeSeconds() + "s");log.info(sw.prettyPrint());return uuid;} catch (Exception e) {log.error("压缩包下载失败 ", e);throw new BusinessCheckException("压缩包下载失败");}}
  1. 根据uuid,下载zip文件(2个接口,一个是根据条件生成zip,另一个根据zip名称下载),此处下载应用了nginx的X-Accel-Redirect,具体使用方法参考springboot X-Accel-Redirect 大文件下载实现
    public void downZip(String path, HttpServletResponse response) {try {String baseUploadPath ="/tmp/zip/";response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("企业二维码", StandardCharsets.UTF_8.toString()) + ".zip");//设置URI给nginx进行内部的跳转response.setHeader("X-Accel-Redirect", "/upload" + baseUploadPath.concat(path).concat(".zip"));} catch (Exception e) {log.error(" 二维码压缩包下载失败 ", e);throw new BusinessCheckException("二维码压缩包下载失败");}}

三、踩坑

  1. linux 和 java 2个进程异步问题

linux命令执行后,和java服务是2个进程。
当linux命令执行过程期间,java下面的业务服务已触发时(比如文件数量较大,而下载接口触发较快时)会造成数据不完整(zip包打包不全,一般一个文件没有)。
此时我们需要利用 读取执行流 + process.waitFor(),等待linux进程结束后再做业务处理。

  1. 关于Process初始化
 Process process = null;// 如果commands拼接的命令中包含空格 会自动识别为2段命令process = new ProcessBuilder(commands).start();// 不支持空格和|process = Runtime.getRuntime().exec(commands);// -c 表示cmd是一条命令,不会被截断process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", commands});
  1. linux for cp 空格识别问题
    执行脚本如下:
for i in  "/data/mnt/www/corp-qr/769847/九台区九台中由 生活服务部.jpg"
docp -n  $i  /data/zip/5e0e67f59c524a4e9851abd3a3dfe0ac
done

此时执行命令报错:cp: 无法获取"/data/mnt/www/corp-qr/769847/九台区九台中由" 的文件状态(stat): 没有那个文件或目录 cp: 无法获取"生活服务部.jpg" 的文件状态(stat): 没有那个文件或目录,linux 会将目标文件解析成2个文件。

解决方案:

"/data/mnt/www/corp-qr/769847/九台区九台中由 生活服务部.jpg" 修改为 "/data/mnt/www/corp-qr/769847/*"cp -n  $i  /data/zip/5e0e67f59c524a4e9851abd3a3dfe0ac 修改为 cp -n  "$i"  /data/zip/5e0e67f59c524a4e9851abd3a3dfe0ac
  1. 执行效率优化
    一千个文件测试结果:
    a. 文件循环时直接打包到zip"/bin/zip -rj " + baseUploadPath.concat(".zip") + " " + baseUploadPath + "/*";效率不如cp 到文件夹下压缩文件夹
    b. 调整压缩率 zip -1
    c. 文件循环时直接cp,由于execCommand执行linux命令要等返回结果再执行,所以效率也不高

  2. cp 文件覆盖问题
    同名文件cp linux会提示是否覆盖,如果通过java执行cp,无法给予是否覆盖的回应,报错:没有那个文件或目录,如果忽略覆盖提示?
    覆盖提示原因:
    在这里插入图片描述
    我们执行cp时 实际linux执行的是cp -i -i 表示覆盖前提示

-- 命令前加反斜线忽略alias
\cp /var/tmp/test.txt /tmp 
-- 使用命令全路径
/bin/cp /var/tmp/test.txt /tmp
-- 先取消别名再复制(不推荐)
unalias cp
-- 不覆盖
cp -n /var/tmp/test.txt /tmp

在这里插入图片描述

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

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

相关文章

Linux中ps命令使用指南

目录 1 前言2 ps命令的含义和作用3 ps命令的基本使用4 常用选项参数5 一些常用情景5.1 查看系统中的所有进程&#xff08;标准语法&#xff09;5.2 使用 BSD 语法查看系统中的所有进程5.3 打印进程树5.4 获取线程信息5.5 获取安全信息5.6 查看以 root 用户身份&#xff08;实际…

vue2+Echarts数据可视化 【帕累托图】

接口得到的数据如下 要经过排序 &#xff0c;计算累计百分比得到数据 蓝色 柱状图数据&#xff1a; 取count字段值 横坐标&#xff1a;取 id值 折线图&#xff1a;根据柱状图的数据计算累计百分比 getInterface(data) {getParetoChart(data).then((res) > {if (res) {thi…

使用YOLOv8训练图集详细教程

准备自己的数据集 训练YOLOv8时&#xff0c;选择的数据格式是VOC&#xff0c;因此下面将介绍如何将自己的数据集转换成可以直接让YOLOv8进行使用。 1、创建数据集 我的数据集都在保存在mydata文件夹&#xff08;名字可以自定义&#xff09;&#xff0c;目录结构如下&#xf…

03.HTML常用标签

HTML常用标签 0.思维导图大纲 1.基本标签 详细介绍 注意 不要用 br 来增加文本之间的行间隔&#xff0c;应使用 p 元素&#xff0c;或后面即将学到的 CSS margin 属性hr 的语义是分隔&#xff0c;如果不想要语义&#xff0c;只是想画一条水平线&#xff0c;那么应当使用 CSS…

node-static 任意文件读取漏洞复现(CVE-2023-26111)

0x01 产品简介 node-static 是 Node.js 兼容 RFC 2616的 HTTP 静态文件服务器处理模块&#xff0c;提供内置的缓存支持。 0x02 漏洞概述 node-static 存在任意文件读取漏洞&#xff0c;攻击者可通过该漏洞读取系统重要文件&#xff08;如数据库配置文件、系统配置文件&#…

扩展学习|商务智能与社会计算

一、概念介绍 &#xff08;一&#xff09;商务智能 商务智能&#xff08;Business Intelligence&#xff0c;简称BI&#xff09;是一种基于数据分析的决策支持系统&#xff0c;旨在帮助企业或组织更好地理解和利用自身数据&#xff0c;发现其中的模式和趋势&#xff0c;并提供…

Spring配置动态数据库

首先创建一个SpringWeb项目——dynamicdb&#xff08;spring-boot2.5.7&#xff09; 然后引入相关依赖lombok、swagger2、mybatis-plus&#xff0c;如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven…

Python数据科学视频讲解:Python的数据运算符

2.9 Python的数据运算符 视频为《Python数据科学应用从入门到精通》张甜 杨维忠 清华大学出版社一书的随书赠送视频讲解2.9节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。内容涵盖数据科学应用的全流程&#xff0c;包括数据科…

stateflow 之图函数、simulink函数和matlab函数使用及案例分析

目录 前言 1. 图函数graph function 2.simulink function 3.matlab function 4.调用stateflow中的几种函数方式 前言 对于stateflow实际上可以做simulink和matlab的所有任务&#xff0c;可以有matlab的m语言&#xff0c;也可以有simulink的模块&#xff0c;关于几种函数在…

头歌-Python 基础

第1关&#xff1a;建模与仿真 1、 建模过程&#xff0c;通常也称为数学优化建模(Mathematical Optimization Modeling)&#xff0c;不同之处在于它可以确定特定场景的特定的、最优化或最佳的结果。这被称为诊断一个结果&#xff0c;因此命名为▁▁▁。 填空1答案&#xff1a;决…

机器学习:从概念到应用

机器学习&#xff1a;从概念到应用 一、引言 随着科技的飞速发展&#xff0c;人工智能已经渗透到我们生活的方方面面。作为人工智能领域的一个重要分支&#xff0c;机器学习正在改变我们的世界。它通过让计算机从数据中学习&#xff0c;实现自我优化和改进&#xff0c;为各行…

【Git从入门到精通 | 02】.gitignore忽略文件不生效怎么办?

这是机器未来的第64篇文章 原文首发地址&#xff1a;https://robotsfutures.blog.csdn.net/article/details/134989872 《Git源码版本管理系列》快速导航&#xff1a; 【Git从入门到精通 | 01】企业Git使用github工作流最佳实践 文章目录 1. 问题场景2. 原因解析3. 处理办法 写…

CTF-Java做题记录合集

文章目录 前言[CISCN 2023]deserbug[MTCTF2022]easyjava[羊城杯 2020]a_piece_of_java[红明谷CTF 2021]JavaWeb 前言 年底都比较忙&#xff0c;很久没有静下心来打过CTF了&#xff0c;最近Java的各种链子也是接触了不少&#xff0c;于是静下心来打算做点Java类的题目&#xff…

linux 网络子系统 摘要

当你输入一个网址并按下回车键的时候&#xff0c;首先&#xff0c;应用层协议对该请求包做了格式定义;紧接着传输层协议加上了双方的端口号&#xff0c;确认了双方通信的应用程序;然后网络协议加上了双方的IP地址&#xff0c;确认了双方的网络位置;最后链路层协议加上了双方的M…

【docker】镜像使用(Nginx 示例)

查看本地镜像列表 docker images删除本地镜像 # docker rmi [容器 ID]docker rmi a6bd71f48f68 查找镜像 docker search nginx 参数介绍 NAME: 镜像仓库源的名称DESCRIPTION: 镜像的描述OFFICIAL: 是否 docker 官方发布STARS: 点赞、喜欢AUTOMATED: 自动构建。 拉去镜像 …

SQL小技巧3:分层汇总

前几天&#xff0c;QQ学习群有个小伙伴问我一个使用SQL分层汇总的问题。 今天正好分享下。 需求描述 在数据报表开发的工作中&#xff0c;经常会遇到需要对数据进行分组汇总的情况。 假设有一个销售数据表sales&#xff0c;包含列region&#xff08;地区&#xff09;、mont…

LInux查看cpu、磁盘、内存、网络的命令

LInux查看cpu、磁盘、内存、网络的命令 1.查看cpu系列2.查看内存方面3.查看磁盘相关 1.查看cpu系列 想知道了cpu性能好不好、忙不忙可以用lscpu、uptime、top、htop。 1.1 top 命令查看系统的实时负载&#xff0c; 包括进程、CPU负载、内存使用等等 top内容详解 项目意义us用…

出海电商访问亚马逊打开很慢!有什么办法可以快速解决?

亚马逊作为全球最大的电商平台&#xff0c;很多中国卖家在平台上做着买卖。亚马逊中国卖每天都要频繁访问亚马逊店铺处理回复邮件和处理订单&#xff0c;上传产品等等事宜&#xff0c;但是时常会遇到打开一个新页面需要等待很长时间&#xff0c;更甚者直接打不开页面! 亚马逊打…

纸质表格扫描转Excel的利器,让您省钱省劲

将纸质表格扫描到电脑Excel上是一种快捷而高效的数字化处理方法&#xff0c;使得数据可以方便地进行编辑、分析和共享。本文将介绍几种常用的方法来完成这项任务。 第一种方法是使用扫描仪。现代扫描仪具备较高的分辨率和颜色还原能力&#xff0c;可以将纸质表格转化为高质量的…

Mybatis插件对指定字段加解密

Mybatis插件对指定字段加解密 1、需求环境&#xff1a;2、需求拆分3、代码实现 (懒得去除敏感信息了&#xff0c;先说明以下全是截图无代码)对存量数据对增量数据 1、需求环境&#xff1a; 在整个项目都结束之后&#xff0c;甲方希望库表内所有涉及到电话号码、详细地址、身份…