需求
需要上传调用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"
以上。