이 글은 다음 글 다음으로 연속해서 작성된 글이다.
https://effectivecode.tistory.com/1729
위의 글의 내용대로 준비를 하고 이제 api에서는 프론트에서 업로드한 파일을 받아서 특정 폴더에 저장을 하고
저장된 경로를 가지고 pdf로 변환을 하기 위해 쉘 스크립트를 실행해야 한다.
실행 해야 할 스크립트의 위치는 docker 컨테이너와 볼륨으로 연결된 경로에 위치 해야한다.
나의 경우 컨테이너 생성 시, 다음과 같이 볼륨을 마운트 하였다.
/home/user1/data/files:/res
따라서, host에서는 /home/user1/data/files/안에 pdf_convert.sh이란 파일을 위치 시키면,
컨테이너 입장에서 /res/pdf_convert.sh로 인식이 된다.
대신 변환해야 할 파일의 경로는 /res로 시작하면 안된다. 왜냐면 이 경로는 host가 알 수 없기에 변환해야할 파일의 경로는
다음과 같이 되어야 정상이다. /home/user1/data/files/변환할 파일명
실제 pdf_convert.sh에서는 실행되는 명령은 host의 CLI명령이기 때문에 해당 CLI명령이 경로를 찾을 수 있어야 하기 때문이다.
그럼 pdf_convert.sh의 파일 내용을 살펴 보자.
#!/bin/sh
input_file=$1
extension="${input_file##*.}"
output_file="${input_file%.*}.pdf"
#스크립트가 있는 위치로 체인지 디렉토리
echo "cd /home/user1" > convert_pipe
#pipe명령을 읽어 들여 실행할 수 있도록 하기 위한 스크립트를 실행
#여기까지 실행되고 나면 docker 컨테이너에서 보내는 명령어를 읽어 들일 준비가 끝.
echo "sh ./pipe_run.sh" > convert_pipe
#실제 파일을 변환하는 명령어를 실행
echo "soffice --headless --convert-to pdf --outdir "$(dirname "$output_file")" "$input_file"" > mypipe
if [ $? -ne 0 ]; then
echo "FAIL"
exit 1
fi
#변환된 파일을 경로를 출력
echo "$output_file"
이렇게 한 이유는 pipe_run.sh파일을 매번 실행해주지 않으면 다음 줄의 명령어를 보내도 읽어 들이지 않았다.
그래서 꼼수를 쓴 것인데, 쉘스크립트를 잘 짜시는 분이라면 이 파일 하나에서 모두 해도 상관없을 것 같다.
다음은 java spring boot의 코드 일부분이다.
String SCRIPT_PATH = rootPath + "/pdf_convert.sh";
String input = "/home/user1/data/files" + "/" + datePath + "/" + filename;
try {
// 쉘 스크립트를 실행합니다.
// ProcessBuilder를 생성하여 쉘 스크립트의 경로와 인자를 전달합니다.
ProcessBuilder processBuilder = new ProcessBuilder(SCRIPT_PATH, input);
Process process = processBuilder.start();
// 쉘 스크립트의 실행 결과를 읽어들입니다.
// InputStreamReader와 BufferedReader를 사용하여 쉘 스크립트의 표준 출력을 읽어들입니다.
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
StringBuilder output = new StringBuilder();
while ((line = reader.readLine()) != null) {
output.append(line);
}
// 쉘 스크립트의 실행이 성공적으로 종료되었는지 확인합니다.
// 쉘 스크립트의 실행이 성공적으로 종료되었다면 exit code는 0이 됩니다.
int exitCode = process.waitFor();
if (exitCode != 0) {
throw new RuntimeException("Script execution failed with exit code: " + exitCode);
}
log.info("\n\n\n >> output : {}\n\n\n", output);
} catch (IOException e) {
log.info("1. exception : {}",e.getLocalizedMessage());
e.printStackTrace();
} catch (InterruptedException e) {
log.info("2. exception : {}",e.getLocalizedMessage());
throw new RuntimeException(e);
}
이게 챗GPT가 작성해준 클래스의 일부분이다. 경로만 바꿨을 뿐....
이 api를 호출할 때 파일을 업로드하면
cd /host/user1
sh ./pipe_run.sh
soffice --headless ... 어쩌구 저쩌구 ~
하는 명령어가 실행되며, 파일이 변환된 걸 확인할 수 있다.
끝.
'IT.인터넷 > Docker' 카테고리의 다른 글
Docker컨테이너에서 host(Linux) 명령어 사용하는 방법(pipe) (0) | 2023.08.04 |
---|---|
도커, compose error : no matching manifest for linux/arm64/v8 in the manifest list entries (for M1, Macbook) (0) | 2022.12.27 |
도커(docker) 컨테이너(container) vi(vim) edit설치 순서 (0) | 2022.12.26 |
Docker (0) | 2022.12.23 |