루아 5.2 이상에서 루아 스크립트를 실행 가능한 .bat 파일에 담는 방법
루아 스크립트를 .bat 파일로 만들면 여러모로 편리합니다. goto가 도입된 루아 5.2 이상에서 루아 스크립트를 .bat 파일에 담는 방법을 소개합니다.
루아 스크립트를 .bat 파일로 만들면 Windows 탐색기에서 바로 실행할 수 있고, 또 외부 명령 실행을 지원하는 다른 프로그램(이를테면 프로그래머용 텍스트 편집기 등)에서 사용하기에도 편합니다.
결론부터 말하면, 다음과 같이 루아 코드 앞에 세 줄의 코드를 추가하고 .bat 파일로 저장하면 됩니다.[1]
hello.bat 파일:
::lua::--[[
@setlocal & set luafile=%0 & if exist %0.bat set luafile=%0.bat
@lua52.exe %luafile% %* & exit /b ]]
print("Hello world") -- 루아 코드
마지막 행의 print("Hello world")
는 루아 코드이고, 처음 세 줄은 기본적으로 .bat 스크립트 명령들입니다.
hello.bat을 실행하면 Windows는 첫 줄의 ::lua::
를 만납니다. .bat 파일에서 :으로 시작하는 줄은 goto의 대상이 되는 이름표(label)로만 해석될 뿐 실제로 실행되지는 않습니다.[2] 따라서 .bat의 구문과는 무관한 --[[는 아무런 오류도 발생하지 않습니다.
둘째 줄 @setlocal & set luafile=%0 & if exist %0.bat set luafile=%0.bat
은 hello.bat
파일을 탐색기에서 더블 클릭하거나 명령 프롬프트에서 hello.bat
으로 실행했을 때뿐만 아니라 명령 프롬프트에서 hello
만으로 실행했을 때나 ..\somedir\hello
처럼 상대 경로로 실행했을 때에도 문제없이 실행되게 하기 위한 것입니다.[3]
셋째 줄에서 이 .bat 파일 자체를 하나의 루아 스크립트로 지정해서 루아 실행기를 실행한 후 .bat 파일 전체의 실행을 끝냅니다(exit /b
). @lua52.exe는 환경에 따라 절대 경로를 추가하거나 @lua53.exe로 바꾸는 등으로 변경하면 되겠습니다.
이제 공은 루아 환경으로 넘어갑니다. 루아 5.2 이상에서 ::식별자::
는 goto의 대상인 이름표입니다. 그다음의 .bat 명령들은 블록 주석 --[[ ... ]] 안에 있으므로 오류가 발생하지 않습니다. 결과적으로 print("Hello world")
행만 실행됩니다.
루아 5.1에서는 .bat에서 의미 있는 goto가 루아에서는 특별한 의미가 없는 하나의 식별자일 뿐이라는 점을 이런 목적으로 활용했습니다. (닥북 한국 모음집의 설치&갱신 스크립트가 기본적으로 이 방법을 사용합니다.)
hello.bat 파일:
goto =goto
print("Hello world")
--[[
:=goto
@setlocal & set luafile=%0 & if exist %0.bat set luafile=%0.bat
@lua5.1.exe %luafile% %*
::]]
첫 줄의 goto =goto
는 .bat에서는 =goto
라는 이름표(아래에 :=goto
로 정의된)로 가는 명령이고, 루아에서는 의미 없는 배정문입니다. 이 방법의 문제점은 루아 스크립트 자체의 출력 이전에 goto =goto
가 출력된다는 점인데(이를 피하기 위해 @goto =goto
로 하면 루아 구문 오류가 발생합니다), 루아 5.2의 goto 이름표를 이용한 방법에는 그런 문제가 없습니다. 루아 5.2에 goto 문이 도입되면서 루아 스크립트를 .bat 파일로 만드는 게 아예 막힌 걸로 생각했는데, 알고 보니 더 나은 해법이 있었네요.
참고로 사실 루아 5.1에서 꼭 goto를 사용할 필요도 없었습니다. .bat에서 rem 파일이 주석(remark)을 뜻하지만 루아에서는 그냥 하나의 식별자라는 점을 이용하는 방법이 있습니다. 이 방법은 루아 5.2 이상에서도 통합니다.
rem = rem --[[
@setlocal & set luafile=%0 & if exist %0.bat set luafile=%0.bat
@lua5.1.exe %luafile% %*
::]]
print("Hello world") -- 루아 코드
그러나 이 방법 역시 첫 줄 rem = rem --[[
이 출력됩니다. 루아 5.1에서는 루아의 문법을 수정하지 않는 한 이를 피할 수 없습니다.
개인적으로 몇 가지 확장 모듈과 .bat 활용 문제 때문에 루아 5.1을 벗어나지 못하고 있었는데, 적어도 하나는 해결이 되었습니다.