윈 도 우 배치파일 작업 완료 후 즉시 Exit하지 않고 몇 초 지난 후에 자동으로 Exit...
2022.12.09 21:24
윈도우OS의 명령 프롬프트에서 수행하는 이른바 "배치파일"의 형식을 아주 간략하게 표현하면
대체로 다음과 같습니다.
--------------------------------------------------------------------------------------
@Echo off
"구체적인 작업을 수행하는 명령의 내용"
pause (또는 exit)
--------------------------------------------------------------------------------------
여기서, 마지막에 pause를 명령하면 상기한 작업을 수행하기를 완료한 후에 곧바로 자동으로 명령 프롬프트 창을 닫지 않고
사용자가 직접 키보드의 키를 눌러 신호를 입력해야 명령 프롬프트 창이 닫힙니다.
그와 반면에, exit를 명령하면 상기한 작업의 수행을 완료한 직후에 곧바로 자동으로 명령 프롬프트 창을 닫습니다.
그런데, 저는 pause와 exit의 전형적인 명령이 아닌 다른 걸 해 보고 싶은데요.
그런 의미에서 제 질문은 다음과 같습니다.
구체적인 작업의 수행을 완료한 직후에 곧바로 명령 프롬프트 창이 자동으로 닫히지 않고 약간의 시간이 지난 후에 자동으로 닫히게 하고 싶습니다.
예를 들어, 배치 작업이 완료되고 5초가 지난 후에 명령 프롬프트 창이 자동으로 닫히게 하는 명령은 어떻게 해야 할까요?
이게 pause 명령과 다른 점은 pause 명령의 경우 사용자가 수동으로 키보드의 키를 눌러야 명령 프롬프트 창이 닫히는 반면,
제 질문은 사용자가 수동으로 키보드의 키를 누르지 않고도 5초가 지나면 무조건 자동으로 명령 프롬프트 창이 닫히도록 한다는 겁니다.
고수분들의 도움을 부탁 드리겠습니다.
꾸벅
댓글 [15]
-
히이이잌 2022.12.09 21:26
-
feynman 2022.12.09 21:56
그렇군요.
알려 주셔서 고맙습니다.
그런데, timeout 명령 아랫줄에 exit를 쓰지 않아도 입력한 시간이 지나니 명령 프롬프트 창이 닫히네요?
exit를 반드시 써야 하나요?
-
메리아 2022.12.09 21:29
여러가지 방법이 있다고는 합니다만
저는 이 방법을 씁니다
ping 127.0.0.1 -n 10 > nul
이 구문이면 10초를 기다립니다.
다만, 실제 사용해보면 10초가 아닌 9초 정도에 해당합니다.
그러므로 10초를 하고 싶으면 11로,
5초를 하고 싶으면 6으로 입력하면 됩니다.
1초가 생략되는거 같으므로 최소값으로는 2를 넣는게 좋겠죠.
-
feynman 2022.12.09 22:01
그렇군요.
위의 분과 다른 방법까지도 추가로 알려 주셔서 고맙습니다.
실제로 시간을 재어 보니, 말씀하신대로 -n 스위치에 입력한 숫자에서 정확하게 1이 빠진 시간정도 걸리네요.
위의 분 말씀까지 종합하면
범용성을 위해서는 ping 명령으로 쓰는 게 가장 적절하겠네요.
위의 분께도 다시 질문드렸지만
ping 명령 다음 아랫줄에 exit를 추가로 넣어야 하나요?
말씀하신 걸 그대로 넣고 exit를 안 썼는데도 지정한 시간이 지나면 명령 프롬프트 창이 자동으로 닫히는 걸 확인은 했습니다만...
확인을 위해 추가로 질문 드려 봅니다.
-
메리아 2022.12.10 10:27
글이 길어져서 먼저 선요약하자면
exit 명령은 함부로 쓰면 안됩니다.
(왜 쓰면 안되는지는 아래에 설명하겠습니다. 정확하게는 쓰면 안될때가 있는겁니다.)
이건 다른 문제의 질문이군요.
ping이든 timeout이든 pause든 그건 그냥 딱 거기까지만에 해당하는 명령입니다.
위 명령들은 그만큼 기다리기만 하는거지
끝내는 부분은 다른 문제죠.
보통은 끝내고 싶은 부분 뒤에 아무것도 없으면 "그냥 아무것도 안해도" 됩니다.
할게 없으면 자동으로 끝납니다.
문제는 중간에 끝내고 싶을때나 뒤에 함수에 해당하는 콜백,서브루틴이 있을 경우입니다
뒤에 실행하고 싶지 않은 주석을 넣기 귀찮은 구문이 있거나
함수처럼 사용하는 서브루틴이 있는 경우에는 중간에 끝낼 필요가 있습니다.
이 끝내는 방법도 여러가지가 있겠습니다만
대표적으로 goto :eof 나 exit 명령이 있습니다.
goto :eof는 서브루틴이 있는 예시에서 자주 보입니다.
http://mwultong.blogspot.com/2007/08/bat-gosub-batch.html
(위 예제는 조금 불완전한데, 서브루틴 끝에도 하나하나 goto :eof를 붙여줘야 서브루틴을 여러개 쓸 수 있습니다)
이 명령은 end of file, 즉 파일 끝으로 가버리라는 뜻입니다.
물론 이미 파일 끝에 해당하면 있어도 그만 없어도 그만입니다.
그런데 서브루틴을 쓰면 끝내고 싶은 위치가 파일 끝일수가 없기 때문에 끝내고 싶은 위치에 저걸 써야하는겁니다.
그리고 문제의 "EXIT" 구문.
다른분들이 다 이거 쓰라 그러죠?
하지만 제가 "쓰지말라"고 하는 이유는 "원치않는 오동작"이 발생할 가능성이 있기 때문입니다.
이게 goto :eof와 다른 점은
goto :eof는 "파일 끝으로 가라"는 명령이지만
exit는 "cmd창을 꺼버려라"는 뜻입니다.
어차피 똑같이 끝내는건데, 별반 차이 없는 얘기 아니냐 싶을텐데 결코 그렇지가 않습니다.
위에서 서브루틴 구문 얘기했는데
링크를 잘 보면 call ~~~ 라는 명령을 씁니다.
그런데 call 명령은 서브루틴만 실행하는게 아니라 "외부파일"도 실행합니다
exit 명령을 쓰면 안되는 이유는
call 명령으로 다른 cmd/bat 파일을 실행시켰을경우
"exit"를 만나면 창을 바로 꺼버립니다.
즉, 메인 cmd가 아닌한 보조 cmd에서 exit를 함부로 쓰면 메인 cmd 자체가 실행이 중단됩니다.
(예제는 뒷부분에 넣겠습니다)
exit를 무조건적으로 쓰면 여러개의 cmd를 쓸 경우 문제가 될 수 있기 때문에
종료의 기본값을 goto :eof로 삼으시는게 좋습니다.
설사 나는 잘 알아도 배포라도 했을경우 다른 분들이 문제가 되기 쉽죠.(뭐, 어차피 call하며 쓸거면 알아서 할일이긴 하지만요)
exit를 쓴 배치파일은 cmd창을 수동으로 열고, 거기서 타이핑해서 cmd를 실행했을경우에도 의도와는 다르게 창이 닫힙니다. 같은 조건이니까요.
(cmd창을 수동으로 열었을땐 보통 닫히길 바라지 않습니다. 특히 더블클릭실행시 오류메시지 안보여서 따로 실행한 경우엔 더 그렇죠. 물론 오류가 나서 그럴땐 exit까지 가지도 않습니다만...)
다만, 사용방법에 따라서는 exit를 써야할 때도 있긴합니다.
특정조건에서라면 무조건 다 씹고 전체를 중단할 필요가 있거나, "새 창"으로 실행되었을때의 얘깁니다.
다른 cmd나 파일을 실행하는 명령은 크게 2가지가 있는데
1. call : "현재창"에서 진행함 (다른 cmd나 파일의 종료를 기다림)
2. start : "새창"을 열어서 진행함 (다른 cmd나 파일의 종료를 기다리지 않으나, /wait 옵션으로 기다릴수는 있음)
start로 다른 cmd창을 열었을경우에는 "창을 자동으로 닫아야" 할때가 많습니다.
start 명령으로 쓸게 확실하고, 의도 또한 서브 창을 자동으로 닫아야한다면 그때는 exit를 쓰면 됩니다.
혹은 무조건 단일 cmd만 쓸게 확실하다면 그때도 써도 됩니다.
그 외에는 많은 경우 트러블이 되기 쉽기 때문애 goto :eof를 기본값으로 생각하고 쓰는게 좋습니다.
아래는 간단한 예제인데, 주석을 지우거나 옮겨가면서 테스트 해보세요.
-----------------------------------------------------------------
>>>> aaa.cmd (보조실행)
@echo off
echo aaa
echo aaa.cmd에서 일시정지
pause
rem timeout /t 5
rem goto :eof
rem exit
-----------------------------------------------------------------
>>>> bbb.cmd (메인실행)
@echo off
echo bbb
call aaa.cmd
rem start "새창" "aaa.cmd"
echo bbb.cmd에서 일시정지
pause
-----------------------------------------------------------------
-
feynman 2022.12.10 18:36
추천을 안 드릴래야 안 드릴 수가 없군요.
겉보기에 간단해 보이는 명령어 하나도 충분히 알고 써야 한다는 사실을 님을 통해 새삼 다시 배웁니다.
귀중한 시간 내어 친절히 설명해 주셔서 고맙습니다.^^
-
네오이즘 2022.12.10 19:05
외부 파일으로 call로 불러올 경우를 대비해서,
이런경우 EXIT/b를 써주면 됩니다.
call로 불려저 온 경우는 해당 파일만 종료되고 call이 아닌경우는 exit와 같이 종료됩니다.
-
ViArPl 2022.12.09 23:42
TIMEOUT [/T] timeout [/NOBREAK]
설명:
이 유틸리티는 지정한 시간(초) 동안 또는 아무 키나 누를 때까지
기다리게 하는 timeout 매개 변수를 받습니다. 또한 키 누름을
무시하게 하는 매개 변수도 받습니다.
매개 변수 목록:
/T timeout 기다릴 시간(초)을 지정합니다.
유효한 범위는 -1에서 99999초까지입니다.
/NOBREAK 키 누름을 무시하고 지정된 시간을 기다립니다.
/? 이 도움말 메시지를 표시합니다.
참고: -1 timeout 값을 지정하면 시간 제한 없이 아무 키나 누를 때까지 기다립니다.
예:
TIMEOUT /?
TIMEOUT /T 10
TIMEOUT /T 300 /NOBREAK
TIMEOUT /T -1
timeout을 사용하는 방법도 있습니다.
-
feynman 2022.12.10 00:20
좋은 정보 알려 주셔서 고맙습니다.
-
밀물 2022.12.10 00:11
exit 명령이 없더라도 더이상 수행할 명령이 없으면 cmd 창은 종료가 됩니다. 그래도 정확성을 위해 exit를 입력해 주는 걸 추천합니다.
-
feynman 2022.12.10 00:20
그렇군요. 가르쳐 주셔서 고맙습니다.^^
-
메리아 2022.12.10 10:35
exit명령은 "현재 시점에서 cmd창을 무조건 끄라"는 명령이라서
의도한게 아니면 함부로 쓰면 안됩니다.
단일실행으로 더블클릭해서 쓸때는 문제가 없으나
cmd창을 수동으로 열고 쓸때는 대개 창을 닫지 않고자 하는데 창을 강제로 닫아버리게 되구요
call명령으로 불러와서 쓸때는 상위 cmd가 있는데도 무시하고 닫아버리게 됩니다.
물론 그게 의도한 동작일 경우에는 써도 됩니다.
(물론 보통의 경우 그럴땐 대개 의도한 동작이 아닙니다)
-
와로 2022.12.10 14:36
보통은 timeout /t 3 /nobreak > nul이나 ping -n 3 127.0.0.1 >nul을 많이들 쓰실겁니다 (3초후에 닫힘)
근데 위 timeout명령줄에 있는 nobreak은 간단한 스크립트에서 대기 시간을 짧게 주고 리디렉션하는건 상관 없는데
대기 시간을 길게 줘야 하는 조건에선 되돌리고 싶어도 말그대로 브레이크를 못걸고 무조건 완료될때까지 기다려야해서 비추합니다
그냥 timeout /t 3 > nul을 쓰던지 갠적으론 ping -n 3 127.0.0.1 >nul 이게 젤 무난하더군요
echo 완료되었습니다.& ping -n 3 127.0.0.1 >nul
메리아님 말씀처럼 어차피 닫히는데 굳이 exit로 더블 체크할 필요 없습니다
윈11 설치할때 우클릭 메뉴 토글할려고 간단하게 만들어 놓은건데 참고해보세요 (2번 제거) Windows_11_우클릭_메뉴_전환.7z
-
feynman 2022.12.10 18:47
그렇군요.
위의 메리아님과 함께 와로님의 설명까지 해서 이해가 좀 더 깊어지게 된 것 같습니다.
고맙습니다. 추천도 함께 드립니다.
그건 그렇고, 대단하십니다.
우클릭 메뉴 전환 배치파일을 개인적으로 만드시기까지 하실 정도면 대단하시네요.
저는 StartAllBack과 같은 써드파티의 은총(?)을 받고 있습니다.
-
와로 2022.12.10 20:49
필요는 삽질의 어머니죠 ㅋㅋ
pe가 아니라면 timeout 명령이 가장 쉽고 편하고, pe에선 보통 ping 명령을 대신 사용합니다.