How to Loop Until a Key is Pressed in Batch Script
Many scripts, especially monitoring tools or refreshable displays, need to run continuously in a loop but also need a way for the user to break out gracefully. A simple PAUSE command halts the script completely, but it doesn't allow the loop to continue running while waiting for input. The ideal solution is a loop that performs its action, waits for a short period, and can be interrupted at any time by a single keypress.
This guide will teach you how to create this functionality using the versatile TIMEOUT command. You will learn how its interrupt behavior and ERRORLEVEL can be used to create an elegant and responsive loop that continues until the user decides to stop it.
The Challenge: Why a Simple GOTO Loop Fails
A basic infinite loop in a batch script is easy to create:
:Loop
ECHO This will run forever...
GOTO :Loop
The only way for a user to stop this is to press Ctrl+C and then confirm they want to terminate the batch job. This is abrupt and doesn't allow the script to perform any cleanup actions. We need a cleaner way to signal the loop to exit.
The Core Method: The TIMEOUT Command's Interrupt Feature
The TIMEOUT command is designed to pause script execution for a specified number of seconds. It has a crucial, built-in feature that makes it perfect for our goal: if a user presses any key during the countdown, TIMEOUT will exit immediately and set a specific ERRORLEVEL.
This gives us a perfect condition to check inside our loop.
Syntax: TIMEOUT /T seconds /NOBREAK > NUL
/T seconds: The number of seconds to wait. This also serves as the "refresh interval" for our loop./NOBREAK: This is the most important switch. It tellsTIMEOUTto ignore Ctrl+C, but to react to any other keypress.> NUL: This hides the countdown output, keeping our script's display clean.
The Script: A Basic Interruptible Loop
This script will print a message every 5 seconds and will exit gracefully the moment the user presses any key.
@ECHO OFF
ECHO Starting a process that will run until you press a key.
ECHO Press any key to stop...
ECHO.
:Loop
ECHO Process is running at %TIME%...
REM Wait for 5 seconds, but allow a keypress to interrupt.
TIMEOUT /T 5 /NOBREAK > NUL
REM Check the ERRORLEVEL. A keypress sets it to a non-zero value.
IF NOT ERRORLEVEL 1 (
GOTO :Loop
)
ECHO.
ECHO Key pressed. Exiting the loop.
The TIMEOUT command's exit code (%ERRORLEVEL%) tells us how it finished:
ERRORLEVEL 0: The timeout completed without interruption. No key was pressed.ERRORLEVEL 1(or any non-zero value): The timeout was interrupted by a keypress.
The logic in our script, IF NOT ERRORLEVEL 1 (GOTO :Loop), translates to: "If the error level is not 1 or greater (meaning, if it is 0), then go back to the start of the loop." The moment a key is pressed, the error level becomes 1, the IF condition becomes false, and the script falls through to the exit message.
An Alternative: Using CHOICE for Specific Keys
The TIMEOUT method is great for stopping on any key. If you want the loop to stop only on a specific key (like 'Q' for Quit), the CHOICE command is a better tool. We can use it with a short timeout.
@ECHO OFF
ECHO Process is running. Press 'Q' to quit.
:Loop
ECHO Doing work at %TIME%...
REM Wait for 1 second for the user to press 'Q'. If not, default to 'C' (Continue).
CHOICE /C QC /N /T 1 /D C > NUL
REM CHOICE sets ERRORLEVEL: 1 for 'Q', 2 for 'C'.
IF %ERRORLEVEL% EQU 1 GOTO :End
GOTO :Loop
:End
ECHO 'Q' was pressed. Exiting.
This is a more advanced pattern for creating interactive loops with specific exit commands.
Common Pitfalls and How to Solve Them
- Forgetting
/NOBREAK: If you omit/NOBREAK, theTIMEOUTcommand will be interrupted by Ctrl+C, but not by other keys. This defeats the purpose. - Forgetting to Hide Output: If you omit
> NUL, theTIMEOUTcommand will print its countdown (Waiting for N seconds, press a key to continue ...), which can clutter your display. - Incorrect
ERRORLEVELCheck: UsingIF %ERRORLEVEL% EQU 0is less robust thanIF NOT ERRORLEVEL 1. The latter is the standard, safer way to check for a "success" (zero) exit code.
Practical Example: A Live Directory Monitor
This script repeatedly clears the screen and displays the contents of the current directory, providing a "live" view of the folder. It continues to refresh every 3 seconds until the user presses any key to stop it.
@ECHO OFF
ECHO --- Live Directory Monitor ---
ECHO Press any key to stop the monitor.
TIMEOUT /T 2 > NUL
:RefreshLoop
CLS
ECHO Contents of %CD% at %TIME%
ECHO (Press any key to exit)
ECHO ===================================
DIR /B
REM Wait for 3 seconds, listening for a keypress.
TIMEOUT /T 3 /NOBREAK > NUL
REM If the timeout completed (no key pressed), loop back.
IF %ERRORLEVEL% EQU 0 GOTO :RefreshLoop
ECHO.
ECHO Monitor stopped by user.
Conclusion
Creating a loop that can be gracefully interrupted by the user is a powerful technique for making interactive and user-friendly monitoring scripts.
- The
TIMEOUT /T N /NOBREAKcommand is the simplest and most effective tool for this. It provides a pause and listens for any keypress. - The outcome is determined by checking
%ERRORLEVEL%:0for a completed timeout,1for a user interruption. - For more complex loops that should only break on a specific key, the
CHOICEcommand with a short timeout is the superior method.
By using these commands, you can move beyond simple, static scripts and create dynamic tools that run until you decide they should stop.