Site Overlay

Java中上传并调用Shell脚本

需求

需要上传调用shell脚本,感觉很多场景都会用到,记录下自己的实现方法,方便后面取用

文件上传

java上传sh文件

@Value("${file.shell.path}")
    private String shellPath;

@PostMapping("/upload")
    @ApiOperation(value = "上传文件", httpMethod = "GET")
    public R<String> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            // 创建上传路径
            File uploadDir = new File(shellPath);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }

            // 生成带有时间戳的文件名
            String originalFileName = file.getOriginalFilename();
            String extension = "";
            int dotIndex = originalFileName.lastIndexOf('.');
            if (dotIndex > 0) {
                extension = originalFileName.substring(dotIndex);
                originalFileName = originalFileName.substring(0, dotIndex);
            }
            SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
            String timestamp = dateFormat.format(new Date());
            String newFileName = originalFileName + "_" + timestamp + extension;

            File destFile = new File(shellPath, newFileName);
            @Cleanup
            FileOutputStream fileOutputStream = new FileOutputStream(destFile);
            StreamUtils.copy(file.getBytes(), fileOutputStream);

            return R.ok(destFile.getPath().replaceAll("\\\\", "/"),"File upload success.");
        } catch (IOException e) {
            return R.fail("File upload failed: " + e.getMessage());
        }
    }

调用触发

上传后触发执行,触发的方法有很多如xxljob这些调度器,这里不赘述,只记录调用的那块逻辑。

    public void execute() throws Exception {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 获取shell脚本
        String command = "/home/shell/test.sh"
        String[] commandList = {command ,"value1","value2" ,"value3","value4"}
        int exitValue = -1;
        BufferedReader bufferedReader = null;
        try {
            // command process
            ProcessBuilder processBuilder = new ProcessBuilder();
            processBuilder.command(commandList);
            processBuilder.redirectErrorStream(true);

            Process process = processBuilder.start();

            BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
            bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));

            // command log
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                log.info(line);
            }

            // command exit
            process.waitFor();
            exitValue = process.exitValue();
        } catch (Exception e) {
            log.error(e);
        } finally {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
        }

        if (exitValue == 0) {
            // default success 执行成功
        } else {
           //  return fail msg 执行失败,失败有很多原因,可以从这个exitValue码值确认
          //  比如为13  就是没给777执行权限,2的话,如果路径没错,就是文件类型没改unix
        }
    }

测试脚本

上传一个测试用的shell脚本 test.sh,可以收参数来执行。

#!/bin/bash
echo "First argument: $1"
echo "Second argument: $2"
echo "Third argument: $3"
echo "Fourth argument: $4"

脚本修改

shell文件上传后需要修改权限以及将文件的类型设置为unix,并且替换换行符。这里携程了一个脚本,方便批量修改权限以及设置文件类型。batch_fix_shell.sh

#!/bin/bash

# 指定目录
DIRECTORY="/home/shell"

# 递归地给目录下的所有文件设置权限
find "$DIRECTORY" -type f -exec chmod 777 {} \;

# 遍历目录中的所有文件
for file in "$DIRECTORY"/*; do
    if [ -f "$file" ]; then
        # 使用vim命令行模式来设置文件类型,添加 -E 选项
        vim -E -c ":set ff=unix" -E -c ":%s/\r$//g" -c ":wq" "$file"
    fi
done

echo "Permissions have been set to 777 for all files in $DIRECTORY"

以上。

发表回复

您的电子邮箱地址不会被公开。

A beliving heart is your magic My heart
欢迎来到Diuut的个人博客,这里是我的一些零零碎碎的知识汇总,希望有能帮到你的内容。 | 蜀ICP备2021011635号-1 | Copyright © 2024 Diuut. All Rights Reserved.