HOWTO · Batch

배치 스크립트에서 함수 생성

이 자습서에서는 Batch Script에서 함수를 만드는 방법에 대해 설명합니다.

이 페이지의 내용

Batch 파일에는 별도의 선언 키워드로 함수를 정의하는 기능이 없습니다. 재사용할 서브루틴은 레이블로 만들고 CALL로 호출합니다. CALL는 해당 레이블 뒤의 명령을 실행한 다음 호출 바로 다음 명령으로 돌아옵니다. 아래 예제는 Windows CMD 문법을 사용하므로 Windows에서 .bat 또는 .cmd 파일로 실행해야 합니다.

Batch 함수의 작동 방식

Batch에서 말하는 “함수”는 보통 서브루틴을 뜻합니다. 레이블이 진입점을 지정하고, CALL :label은 그곳으로 제어를 옮기면서 돌아올 위치를 보존합니다. 레이블만으로 별도의 범위가 생기거나 자동으로 반환되지는 않습니다. 서브루틴 안에서 EXIT /B를 사용하면 호출한 곳으로 돌아갑니다. 명시적으로 반환하지 않으면 실행이 다음 레이블과 명령으로 이어질 수 있습니다. EXIT /B는 서브루틴으로 호출된 상태가 아닐 때 현재 배치 스크립트를 종료합니다.

Batch 함수를 정의하고 호출하기

호출 코드를 레이블보다 앞에 두고, 메인 본문 끝에 GOTO :EOF를 넣어 서브루틴으로 그대로 흘러 들어가지 않게 합니다. 생성되는 스크립트에서 서브루틴은 인사말을 출력한 뒤 호출한 곳으로 돌아옵니다.

CMD가 여기서 실행되었다고 오해하지 않도록, 작은 Windows CMD 스크립트를 확인하려면 이 Python 스크립트를 실행하세요. 이 스크립트는 Batch 소스 코드를 출력합니다. 출력된 내용을 .bat 또는 .cmd 파일로 저장한 다음 Windows CMD에서 실행하세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

print('''@echo off
call :greet "Ada"
echo Back in the main script.
goto :eof

:greet
echo Hello, %~1!
exit /b 0''')
@echo off
call :greet "Ada"
echo Back in the main script.
goto :eof

:greet
echo Hello, %~1!
exit /b 0

생성된 스크립트는 Windows CMD용입니다. Python은 소스 코드를 출력할 뿐, 이를 실행하지 않습니다. GOTO :EOF는 메인 흐름을 끝내고, 호출된 레이블의 EXIT /B 0은 성공 상태 코드를 반환합니다. 0은 일반적인 성공 코드이며, 0이 아닌 코드는 호출자에게 실패를 알릴 수 있습니다. 예제의 레이블과 화면에 표시되는 문구는 영어로 그대로 유지됩니다.

Batch 함수에 인수 전달하기

CALL 명령에서 레이블 뒤에 인수를 공백으로 구분해 씁니다. 서브루틴 안에서 %1은 첫 번째 인수, %2는 두 번째 인수이며 이후 인수도 같은 방식으로 이어집니다. 첫 번째 인수에서 바깥쪽 따옴표를 제거하려면 %~1를 사용하는 편이 좋습니다. 물결표를 붙여도 모든 명령에 값을 안전하게 삽입할 수 있는 것은 아니므로, 경로나 텍스트로 사용할 값은 따옴표로 감싸세요.

이 Python 예제는 공백이 포함된 인수 하나를 전달하는 완전한 Batch 스크립트를 출력합니다. 출력된 소스 코드를 .bat 또는 .cmd 파일로 저장해 Windows CMD에서 실행하세요. :show 서브루틴은 값을 %~1로 읽습니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

print("""@echo off
call :show "Ada Lovelace"
goto :eof

:show
echo Name: %~1
exit /b 0""")
@echo off
call :show "Ada Lovelace"
goto :eof

:show
echo Name: %~1
exit /b 0

값에 공백이나 명령 메타문자가 들어갈 수 있다면 인수 확장을 따옴표로 감싼 비교식이나 따옴표로 감싼 SET 대입식 안에서 처리하세요. Batch는 여러 단계로 구문을 확장하므로 %, &, | 같은 문자가 포함된 값은 특히 주의해야 합니다. 예제의 레이블과 화면에 표시되는 문구는 영어로 그대로 유지됩니다.

반환값과 종료 코드

Batch에는 함수 반환값을 담는 내장 슬롯이 없습니다. 흔히 결과는 환경 변수에 넣고, 성공 여부나 실패 여부는 서브루틴의 종료 코드로 별도로 전달합니다. 이 Python 예제는 인수 두 개를 받는 서브루틴을 호출하고, CALL 바로 다음에 상태 코드를 확인한 뒤 성공하면 결과 변수를 읽는 완전한 Batch 스크립트를 출력합니다. 출력된 소스 코드를 .bat 또는 .cmd 파일로 저장해 Windows CMD에서 실행하세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

print("""@echo off
setlocal EnableExtensions
call :add 5 10
if errorlevel 1 goto add_failed
echo Sum: %sum%
goto :eof

:add_failed
echo Addition failed.
goto :eof

:add
if "%~1"=="" exit /b 1
if "%~2"=="" exit /b 1
setlocal
set /a "_sum=%~1 + %~2"
endlocal & set "sum=%_sum%"
exit /b 0""")
@echo off
setlocal EnableExtensions
call :add 5 10
if errorlevel 1 goto add_failed
echo Sum: %sum%
goto :eof

:add_failed
echo Addition failed.
goto :eof

:add
if "%~1"=="" exit /b 1
if "%~2"=="" exit /b 1
setlocal
set /a "_sum=%~1 + %~2"
endlocal & set "sum=%_sum%"
exit /b 0

레이블은 위치 인수 값을 %~1와 %~2로 읽습니다. SETLOCAL은 임시 _sum 변수를 로컬 범위에 둡니다. 같은 명령줄에서 CMD는 ENDLOCAL을 실행하기 전에 %_sum%를 확장한 다음, 그 값을 호출자의 sum 변수에 대입합니다. ENDLOCAL & SET은 한 줄로 함께 두세요. 이 예제는 정수 인수를 전제로 합니다. 인수가 없으면 상태 코드 1을 반환하고, 덧셈이 끝나면 상태 코드 0을 반환합니다. 코드와 화면에 표시되는 문구 및 레이블은 영어로 그대로 유지됩니다.

Batch 함수에서 오류 처리하기

필수 입력은 서브루틴 초반에 확인하고, 입력이 없으면 0이 아닌 상태 코드를 반환하세요. 이 Python 예제는 필수 입력이 없는 경우와 있는 경우에 같은 검사 레이블을 호출하는 완전한 Batch 스크립트를 출력합니다. 각 if errorlevel 1 검사는 해당 CALL 바로 뒤에 있습니다. 출력된 소스 코드를 .bat 또는 .cmd 파일로 저장해 Windows CMD에서 실행하세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

print("""@echo off
call :require_value
if errorlevel 1 (
    echo Missing input: rejected with status 1.
) else (
    echo Missing input: accepted.
)

call :require_value "report.txt"
if errorlevel 1 (
    echo Valid input: rejected.
) else (
    echo Valid input: accepted with status 0.
)
goto :eof

:require_value
if "%~1"=="" exit /b 1
exit /b 0""")
@echo off
call :require_value
if errorlevel 1 (
    echo Missing input: rejected with status 1.
) else (
    echo Missing input: accepted.
)

call :require_value "report.txt"
if errorlevel 1 (
    echo Valid input: rejected.
) else (
    echo Valid input: accepted with status 0.
)
goto :eof

:require_value
if "%~1"=="" exit /b 1
exit /b 0

첫 번째 호출은 필수 값이 없으므로 실패 분기로 이동하고, 두 번째 호출은 성공 분기로 이동합니다. if errorlevel 1은 현재 오류 수준이 1 이상이라는 뜻입니다. 정확한 코드가 중요하다면 더 높은 코드부터 내림차순으로 확인하세요. 유효한 인수가 있으면 서브루틴이 작업을 진행한 뒤 EXIT /B 0으로 끝낼 수 있습니다.

서브루틴에서 반환할 때는 EXIT 대신 EXIT /B를 사용하세요. EXIT는 CMD 세션을 닫지만, EXIT /B는 현재 배치 컨텍스트에서 반환합니다. CALL가 존재하지 않는 레이블을 대상으로 하면 CMD가 오류를 보고합니다. 레이블 이름을 일관되게 쓰고 서브루틴 호출과 레이블이 짝을 이루도록 눈에 띄게 배치하면 문제를 진단하기 쉽습니다. Python 예제는 Batch 소스 코드를 출력할 뿐 실행하지 않으므로, Batch 동작을 확인하려면 저장한 스크립트를 Windows CMD에서 실행하세요. 예제 코드와 화면에 표시되는 문구 및 레이블은 영어로 그대로 유지됩니다.