본문 바로가기
IT/Java

Bash 스크립트에서 Java 실행 시 args.length가 예상치 못하게 나오는 문제 해결 (CRLF vs LF)

by SpringUpOhWell! 2025. 10. 2.
반응형

리눅스 환경에서 Bash 스크립트를 통해 Java 프로그램을 실행할 때, 인자를 전달하지 않았는데도 Java의 args.length가 1로 나오는 이상한 상황을 겪은 적 있나요? 저도 최근에 이 문제를 마주쳤고, 원인을 파악하고 해결한 과정을 공유하려고 합니다. 특히, Windows와 Linux 간 줄 끝 문자(CRLF vs LF) 차이에서 비롯된 문제였어요. 이 글에서는 문제 원인과 해결 방법을 간단히 정리해드릴게요!

문제 상황
run.sh라는 Bash 스크립트를 통해 Java 프로그램을 실행했어요. 스크립트는 다음과 같이 작성되어 있었습니다:

java -cp classpath -Dprop=value ki.method $1 $2

이 스크립트를 인자 없이 실행(./run.sh)했는데, Java 코드에서 args.length가 0이 아니라 1로 나왔어요. 더 놀라운 건 args[0]을 출력해보니 빈 문자열처럼 보였지만, args[0].charAt(0)의 ASCII 값을 찍어보니 13이 나왔습니다. 이건 캐리지 리턴(CR, \r) 문자였죠!

원인: CRLF 줄 끝 문자
문제의 원인은 run.sh 파일이 Windows 환경에서 작성되었거나, Windows 스타일 줄 끝 문자(CRLF, \r\n)를 포함하고 있었기 때문이에요. 리눅스에서는 줄 끝 문자로 LF (\n)만 사용하는데, CRLF가 포함된 스크립트를 리눅스에서 실행하면 \r (ASCII 13)이 인자나 문자열에 섞일 수 있어요.
제 경우, run.sh 파일이 CRLF로 저장되어 있어서 Bash가 이를 처리하는 과정에서 \r이 args[0]로 전달된 거였어요. 그래서 args.length가 1이 되고, args[0]이 눈에 보이지 않는 \r 문자로 채워진 거죠.

확인 방법
줄 끝 문자 확인: 스크립트 파일에 \r이 포함되어 있는지 확인하려면 다음 명령어를 사용하세요:

cat -v run.sh

줄 끝에 ^M이 보인다면 CRLF가 포함된 겁니다.

인자 디버깅: 스크립트 실행 시 어떤 인자가 전달되는지 확인하려면:

bash -x ./run.sh

이 명령어는 스크립트 실행 과정을 보여주며, java ki.inter 뒤에 \r 같은 이상한 인자가 붙는지 확인할 수 있어요.

Java에서 args 확인: Java 코드에서 args[0]의 내용을 자세히 확인하려면:


if (args.length > 0) {
    System.out.println("args[0]: '" + args[0] + "'");
    System.out.println("args[0] length: " + args[0].length());
    for (char c : args[0].toCharArray()) {
        System.out.println("Char: " + c + ", ASCII: " + (int) c);
    }
} else {
    System.out.println("No args provided");
}



제 경우, ASCII: 13이 출력되며 \r이 문제임을 알게 됐어요.

해결 방법
문제를 해결하려면 run.sh 파일을 리눅스 스타일 줄 끝(LF)으로 변환하면 됩니다. 다음 두 가지 방법 중 하나를 사용하세요:
dos2unix 명령어:
dos2unix run.sh
이 명령어는 CRLF를 LF로 변환해줍니다.
sed로 직접 제거:
sed -i 's/\r$//' run.sh
파일 끝의 \r을 제거해요.
변환 후 스크립트를 다시 실행하면 args.length가 0으로 정상 출력되고, \r이 인자로 전달되지 않아요.

추가 팁
Git 설정 확인: Git을 사용할 때 Windows와 Linux 간 파일을 공유하면 CRLF가 섞일 수 있어요. .gitattributes 파일에 text eol=lf를 추가해 모든 파일이 LF로 저장되도록 설정하세요.
편집기 설정: VS Code나 다른 편집기에서 파일을 저장할 때 줄 끝을 LF로 설정하세요. 예: VS Code에서 Files: Eol을 \n으로 설정.

인자 처리 주의: Bash 스크립트에서 $1, $2를 사용할 때 ${1:-""} 같은 default 값 설정이 있다면, 의도치 않은 빈 문자열이나 제어 문자가 전달될 수 있으니 주의하세요.

결론
Windows와 Linux 간 줄 끝 문자 차이(CRLF vs LF)는 간단하지만 골치 아픈 문제를 일으킬 수 있어요. 특히 Bash 스크립트로 Java 프로그램을 실행할 때, \r 같은 제어 문자가 인자로 섞이면 디버깅이 까다로워지죠. cat -v, dos2unix, 그리고 Java 디버깅 코드를 활용해 문제를 빠르게 잡아낼 수 있으니, 비슷한 문제로 고민 중이라면 이 방법을 시도해보세요!
혹시 비슷한 경험 있으시면 댓글로 공유 부탁드려요! 😊

반응형

'IT > Java' 카테고리의 다른 글

스타터  (0) 2023.12.17
interface 의 구현  (0) 2013.08.14
자바의 특징  (0) 2013.07.17

댓글