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