最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java如何執(zhí)行l(wèi)inux命令

 更新時間:2024年05月06日 09:58:28   作者:Mr-Wanter  
這篇文章主要介紹了java如何執(zhí)行l(wèi)inux命令問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

前言

java 執(zhí)行l(wèi)inux 命令;

本文模擬復(fù)制linux文件到指定文件夾后打zip包后返回zip名稱,提供給下載接口下載zip;

一、linux命令執(zhí)行

linux命令執(zhí)行

Process process = Runtime.getRuntime().exec

Process process = new ProcessBuilder(commands).start();
   
    /**
     * 執(zhí)行Linux命令
     */
    public static void execCommand(String commands) throws IOException {
        Process process = null;
        BufferedReader reader = null;
        try {
            //創(chuàng)建進(jìn)程實(shí)例執(zhí)行Linux命令
            process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", commands});
            // 獲取標(biāo)準(zhǔn)輸入流
            reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                //log.info("linux----" + line);
            }
            // 等待進(jìn)程結(jié)束
            int exitCode = process.waitFor();
            if (exitCode != 0) {
                log.error("執(zhí)行Linux命令異常,exitCode={},linux command={}", exitCode, commands);
                throw new BusinessCheckException("執(zhí)行Linux命令異常");
            }
        } catch (IOException | InterruptedException e) {
            log.error("執(zhí)行Linux命令異常", e);
            throw new BusinessCheckException("執(zhí)行Linux命令異常");
        } finally {
            if (reader != null) {
                reader.close();
            }
            if (process != null) {
                process.destroy();
            }
        }
    }

二、使用步驟

1.通過linux命令

打包目標(biāo)數(shù)據(jù)到zip

public String downToZip(CorpQrCodeReq req, HttpServletResponse response) {
   		StopWatch sw = new StopWatch();
		// 參數(shù)校驗(yàn)
        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());
            // 拼接被復(fù)制的文件地址
            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("執(zhí)行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";
            //執(zhí)行cp命令
            execCommand(sb);
            sw.stop();
            log.info(sw.getLastTaskName() + sw.getTotalTimeSeconds() + "s");
            sw.start("執(zhí)行壓縮命令");
            //執(zhí)行壓縮命令 統(tǒng)一壓縮比一個一個壓縮進(jìn)去效率高 
            //-j忽略源文件路徑,直接打包目標(biāo)文件
            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("壓縮包下載失敗");
        }
    }

2.根據(jù)uuid

下載zip文件(2個接口,一個是根據(jù)條件生成zip,另一個根據(jù)zip名稱下載)

此處下載應(yīng)用了nginx的X-Accel-Redirect

具體使用方法參考springboot X-Accel-Redirect 大文件下載實(shí)現(xiàn)

    public void downZip(String path, HttpServletResponse response) {
        try {
            String baseUploadPath ="/tmp/zip/";
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("企業(yè)二維碼", StandardCharsets.UTF_8.toString()) + ".zip");
            //設(shè)置URI給nginx進(jìn)行內(nèi)部的跳轉(zhuǎn)
            response.setHeader("X-Accel-Redirect", "/upload" + baseUploadPath.concat(path).concat(".zip"));
        } catch (Exception e) {
            log.error(" 二維碼壓縮包下載失敗 ", e);
            throw new BusinessCheckException("二維碼壓縮包下載失敗");
        }
    }

三、踩坑

1.linux 和 java 2個進(jìn)程異步問題

linux命令執(zhí)行后,和java服務(wù)是2個進(jìn)程。

當(dāng)linux命令執(zhí)行過程期間,java下面的業(yè)務(wù)服務(wù)已觸發(fā)時(比如文件數(shù)量較大,而下載接口觸發(fā)較快時)會造成數(shù)據(jù)不完整(zip包打包不全,一般一個文件沒有)。

此時我們需要利用 讀取執(zhí)行流 + process.waitFor(),等待linux進(jìn)程結(jié)束后再做業(yè)務(wù)處理。

2.關(guān)于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});

3.linux for cp 空格識別問題

執(zhí)行腳本如下:

for i in  "/data/mnt/www/corp-qr/769847/九臺區(qū)九臺中由 生活服務(wù)部.jpg"
do
 cp -n  $i  /data/zip/5e0e67f59c524a4e9851abd3a3dfe0ac
done

此時執(zhí)行命令報錯:

cp: 無法獲取"/data/mnt/www/corp-qr/769847/九臺區(qū)九臺中由" 的文件狀態(tài)(stat): 沒有那個文件或目錄 cp: 無法獲取"生活服務(wù)部.jpg" 的文件狀態(tài)(stat): 沒有那個文件或目錄

linux 會將目標(biāo)文件解析成2個文件。

解決方案:

"/data/mnt/www/corp-qr/769847/九臺區(qū)九臺中由 生活服務(wù)部.jpg" 修改為 "/data/mnt/www/corp-qr/769847/*" 或
cp -n  $i  /data/zip/5e0e67f59c524a4e9851abd3a3dfe0ac 修改為 cp -n  "$i"  /data/zip/5e0e67f59c524a4e9851abd3a3dfe0ac

5.執(zhí)行效率優(yōu)化

一千個文件測試結(jié)果:

  • a. 文件循環(huán)時直接打包到zip"/bin/zip -rj " + baseUploadPath.concat(".zip") + " " + baseUploadPath + "/*";效率不如cp 到文件夾下壓縮文件夾
  • b. 調(diào)整壓縮率 zip -1
  • c. 文件循環(huán)時直接cp,由于execCommand執(zhí)行l(wèi)inux命令要等返回結(jié)果再執(zhí)行,所以效率也不高

6.cp 文件覆蓋問題

同名文件cp linux會提示是否覆蓋,如果通過java執(zhí)行cp,無法給予是否覆蓋的回應(yīng),報錯:沒有那個文件或目錄,如果忽略覆蓋提示?

覆蓋提示原因:

我們執(zhí)行cp時 實(shí)際linux執(zhí)行的是cp -i ,-i 表示覆蓋前提示

-- 命令前加反斜線忽略alias
\cp /var/tmp/test.txt /tmp 
-- 使用命令全路徑
/bin/cp /var/tmp/test.txt /tmp
-- 先取消別名再復(fù)制(不推薦)
unalias cp
-- 不覆蓋
cp -n /var/tmp/test.txt /tmp

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解JAVA 函數(shù)式編程

    詳解JAVA 函數(shù)式編程

    這篇文章主要介紹了JAVA 函數(shù)式編程的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • SpringBoot入門系列之JPA mysql

    SpringBoot入門系列之JPA mysql

    這篇文章主要介紹了SpringBoot入門系列之JPA mysql的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 一文讀懂a(chǎn)va中的Volatile關(guān)鍵字使用

    一文讀懂a(chǎn)va中的Volatile關(guān)鍵字使用

    volatile關(guān)鍵字的作用保證了變量的可見性(visibility)。被volatile關(guān)鍵字修飾的變量,如果值發(fā)生了變更,其他線程立馬可見,避免出現(xiàn)臟讀的現(xiàn)象。這篇文章主要介紹了ava中的Volatile關(guān)鍵字使用,需要的朋友可以參考下
    2020-03-03
  • Java后端返回PDF預(yù)覽給前端的實(shí)現(xiàn)

    Java后端返回PDF預(yù)覽給前端的實(shí)現(xiàn)

    前端要預(yù)覽服務(wù)器PDF 可直接將要blob流返回給前端,即可用瀏覽器自帶pdf預(yù)覽功能打開,本文就來介紹一下如何實(shí)現(xiàn),感興趣的可以了解一下
    2023-09-09
  • 詳解Spring中InitializingBean接口的功能

    詳解Spring中InitializingBean接口的功能

    這篇文章主要介紹了Spring中InitializingBean接口的功能,講述了spring中InitializingBean接口的功能簡介說明,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • JavaScript Date時間對象的常用操作方法總結(jié)

    JavaScript Date時間對象的常用操作方法總結(jié)

    本文介紹了JavaScript中Date對象的常用操作方法,包括創(chuàng)建、獲取、設(shè)置本地及UTC時間等,幫助開發(fā)者靈活處理日期與時間的相關(guān)需求,需要的朋友可以參考下
    2025-10-10
  • java實(shí)現(xiàn)文件打包壓縮輸出到瀏覽器下載

    java實(shí)現(xiàn)文件打包壓縮輸出到瀏覽器下載

    這篇文章主要介紹了java實(shí)現(xiàn)文件打包壓縮輸出到瀏覽器下載,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java設(shè)計模式--橋接模式詳解

    java設(shè)計模式--橋接模式詳解

    這篇文章主要為大家詳細(xì)介紹了java設(shè)計模式之橋接模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-07-07
  • Hibernate中實(shí)現(xiàn)增刪改查的步驟詳解

    Hibernate中實(shí)現(xiàn)增刪改查的步驟詳解

    本篇文章主要介紹了Hibernate中實(shí)現(xiàn)增刪改查的步驟與方法,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • 將Java程序打包成EXE文件的實(shí)現(xiàn)方式

    將Java程序打包成EXE文件的實(shí)現(xiàn)方式

    這篇文章主要介紹了將Java程序打包成EXE文件的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04

最新評論

洪洞县| 晋州市| 施甸县| 仁怀市| 磴口县| 大化| 女性| 达日县| 千阳县| 姚安县| 罗田县| 淮南市| 深水埗区| 长兴县| 万全县| 连城县| 渭南市| 利辛县| 垫江县| 延安市| 香港 | 铁岭县| 宜川县| 宾川县| 恩施市| 天峨县| 信丰县| 永顺县| 屏南县| 峨边| 溧水县| 大同县| 抚顺市| 揭东县| 赤水市| 竹山县| 翁牛特旗| 花莲县| 大邑县| 华宁县| 巴南区|