Skip to content

fix: TaskletShellStep이 줄 분리 결과로 잘못된 명령을 실행하는 문제 수정 - #326

Open
wantaekchoi wants to merge 1 commit into
eGovFramework:mainfrom
wantaekchoi:fix/tasklet-shell-step-line-split-regex
Open

fix: TaskletShellStep이 줄 분리 결과로 잘못된 명령을 실행하는 문제 수정#326
wantaekchoi wants to merge 1 commit into
eGovFramework:mainfrom
wantaekchoi:fix/tasklet-shell-step-line-split-regex

Conversation

@wantaekchoi

@wantaekchoi wantaekchoi commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

수정 사유 Reason for modification

  • 버그수정 Bug fixes
  • 기능개선 Enhancements
  • 기능추가 Adding features
  • 기타 Others

수정된 소스 내용 Modified source

TaskletShellStep.execute()의 줄 분리 코드에서 두 가지가 나옵니다.

1. 정규식이 개행이 아닌 물음표에서도 자른다

정규식이 "[\r?\n]+"인데 문자 클래스 안에서 ?는 수량자가 아니라 리터럴입니다. \r?\n을 의도한 것으로 보이지만 실제로는 \r·?·\n 셋 중 아무 문자에서나 잘립니다.

"echo a?b".split("[\r?\n]+")  ->  ["echo a", "b"]

조각마다 별도 프로세스로 실행됩니다. 물음표는 파일명 패턴이나 URL 질의 문자열에 흔히 들어가고, ShellScriptSupport가 막는 메타문자 목록에도 없어 그대로 통과합니다.

2. 빈 줄이 빈 명령으로 실행된다

정규식을 고쳐도 스크립트가 개행으로 시작하면 첫 원소가 빈 문자열이 됩니다. XML 설정에서 <value> 안에 줄바꿈을 넣는 건 흔한 형태입니다.

"\necho hello"         -> ["", "echo hello"]           -> IllegalArgumentException: command must not be null or empty
"echo a\n   \necho b"  -> ["echo a", "   ", "echo b"]  -> IllegalArgumentException: Empty command

공백만 있는 원소는 shellCmd의 빈 문자열 가드를 통과한 뒤 trim() 결과가 비어 Runtime.exec에서 죽습니다.

AS-IS

String[] arrCmdLine = shellScript.split("[\\r?\\n]+");

int resultShellScript = 0;
if (arrCmdLine.length == 0) { // single line
    resultShellScript = ShellScriptSupport.shellCmd(shellScript, encoding);
    ...
} else { // multiline
    for (String s : arrCmdLine) { ... }
}

TO-BE

String[] arrCmdLine = shellScript.split("[\\r\\n]+");

int resultShellScript = 0;
for (String s : arrCmdLine) {
    if (s.trim().isEmpty()) {
        continue;
    }
    ...
}

arrCmdLine.length == 0 분기도 함께 지웠습니다. 이 분기는 수정 전에는 도달할 수 있습니다 — "???"처럼 전부 구분자로 취급되는 문자열이면 split이 빈 배열을 돌려주기 때문입니다. 정규식을 고치면 구분자가 \r·\n뿐이라 전부 구분자인 문자열은 위쪽 shellScript.trim().equals("") 가드에서 이미 걸러지므로 도달할 수 없게 됩니다. 분기 본문도 원소가 하나일 때의 루프와 결과가 같습니다.

영향 범위

?가 없고 빈 줄로 시작하지 않는 스크립트는 결과가 같습니다. +를 그대로 두어 CRLF와 연속 개행이 하나로 묶이는 동작도 종전과 같습니다.

의도로 보이는 \r?\n으로 바꾸지 않은 이유는 기존 동작이 깨지기 때문입니다. \r만으로 줄을 나눈 스크립트는 아예 분리되지 않고, 빈 줄이 연속되면 빈 문자열 원소가 더 늘어납니다.

JUnit 테스트 JUnit tests

  • JUnit 테스트 JUnit tests
  • 수동 테스트 Manual testing

TaskletShellStepTest 4건을 추가했습니다.

수정 지점만 되돌린 상태(RED)

[ERROR] TaskletShellStepTest.executeSingleLineContainingQuestionMark » IO Cannot run program "b": Exec failed, error: 2 (No such file or directory)
[ERROR] TaskletShellStepTest.executeScriptStartingWithNewline » IllegalArgument command must not be null or empty
[ERROR] TaskletShellStepTest.executeScriptWithBlankLine » IllegalArgument Empty command

수정 후(GREEN, org.egovframe.rte.bat.core 모듈 전체)

[INFO] Tests run: 78, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS

두 가지를 함께 고친다. 둘 다 같은 줄 분리 코드가 원인이다.

1) 정규식이 개행이 아닌 물음표에서도 자른다

줄 분리에 쓰는 정규식이 "[\r?\n]+"인데, 문자 클래스 안에서 ?는 수량자가 아니라
리터럴이다. \r?\n(선택적 캐리지리턴 + 개행)을 의도한 것으로 보이지만 실제로는
\r, ?, \n 세 문자 중 아무거나에서 잘린다. 그래서 물음표가 든 한 줄짜리 명령이
여러 조각으로 나뉘어 각각 별도 프로세스로 실행된다. 물음표는 파일명 패턴이나
URL 질의 문자열에 흔히 들어가고 ShellScriptSupport가 막는 메타문자 목록에도
없어 그대로 통과한다.

  echo a?b  ->  ["echo a", "b"]  ->  b를 프로그램으로 실행 시도

문자 클래스에서 ?를 빼면 \r과 \n만 구분자가 된다. +가 붙어 있어 CRLF와 연속
개행은 종전대로 하나로 묶인다. 의도로 보이는 \r?\n으로 바꾸지 않은 것은
\r만으로 줄을 나눈 스크립트가 아예 분리되지 않고, 연속된 빈 줄이 빈 문자열
원소를 만들어 shellCmd가 IllegalArgumentException으로 죽기 때문이다.

2) 빈 줄이 빈 명령으로 실행된다

정규식을 고쳐도 스크립트가 개행으로 시작하면 첫 원소가 빈 문자열이 된다.
XML 설정에서 <value> 안에 줄바꿈을 넣는 건 흔한 형태다.

  "\necho hello"        -> ["", "echo hello"]  -> IllegalArgumentException: command must not be null or empty
  "echo a\n   \necho b" -> ["echo a", "   ", "echo b"] -> IllegalArgumentException: Empty command

공백만 있는 원소는 shellCmd의 빈 문자열 가드도 통과한 뒤 trim() 결과가 비어
Runtime.exec에서 죽는다. 루프에서 빈 줄을 건너뛰도록 했다.

arrCmdLine.length == 0 분기도 함께 지웠다. 이 분기는 수정 전에는 도달 가능했지만
("???"는 전부 구분자로 취급돼 빈 배열이 된다) 정규식을 고치면 구분자가 \r\n뿐이라
전부 구분자인 문자열은 위쪽 trim() 가드에서 이미 걸러진다. 분기 본문도 원소가
하나일 때의 루프와 결과가 같다.
@wantaekchoi
wantaekchoi force-pushed the fix/tasklet-shell-step-line-split-regex branch from b4e547b to d5b7788 Compare August 13, 2026 12:31
@wantaekchoi wantaekchoi changed the title fix: TaskletShellStep이 개행이 아닌 물음표에서도 셸 명령을 쪼개는 문제 수정 fix: TaskletShellStep이 줄 분리 결과로 잘못된 명령을 실행하는 문제 수정 Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant