set /p: read user input or the first line of a file in a batch file
- tool
- Command Prompt (cmd)
- command
- set
- flag
- /p
- default
- none (set without /p assigns a literal value)
set /p NAME=Enter your name: prints the prompt, waits for the user to press Enter and stores the typed line in NAME. The prompt text is optional. With input redirected, set /p LINE=<file.txt stores the first line of the file. If the input is empty, set /p leaves the variable unchanged (it does not clear it) and sets ERRORLEVEL to 1, so clear the variable first.
set "ANSWER="
set /p "ANSWER=Continue? [y/n] "
if /i "%ANSWER%"=="y" echo continuingBehaviour
> name.txt echo Alice
>> name.txt echo Bob
set /p NAME=<name.txt
echo first line: %NAME%
set "KEEP=old value"
set /p KEEP=<nul
echo after empty input: %KEEP% (ERRORLEVEL=%ERRORLEVEL%)
set /p "=text without a newline" <nul
echo ... continues on the same lineOutput
first line: Alice after empty input: old value (ERRORLEVEL=1) text without a newline ... continues on the same line
The last two lines show a common trick: set /p "=text" <nul prints text without a line break, because the prompt is printed and the empty input is discarded.
Details
| Case | Result |
|---|---|
| User presses Enter without typing | variable keeps its previous value, ERRORLEVEL 1 |
| set "VAR=" first | variable is undefined after empty input; test with if not defined VAR |
| Input with spaces | stored as typed, including spaces |
| Input with & | > < | stored as text; quote it when you use it: echo "%VAR%" |
| set /p VAR=<file | first line of the file only (use for /f for all lines) |
For a single key choice with a timeout and default, choice /c yn /t 10 /d n /m "Continue" sets ERRORLEVEL to the position of the chosen key (1 for y, 2 for n) and does not need Enter.
When to use set /p
Use set /p in interactive batch files that ask a person for a value (a name, a path, a yes/no answer) and in scripts that need the first line of a small file, such as a version number written by a build step. For anything that must run unattended, read arguments or environment variables instead: in a scheduled task or a CI job nobody is there to answer the prompt.
Pitfalls
Reading the value inside a block. Inside if (...) or for ... do (...), cmd expands %VAR% once, when it parses the whole block. The value typed during that block is stored, but %VAR% still shows the old one. Use delayed expansion and !VAR!, as the second example shows:
setlocal EnableDelayedExpansion
> answer.txt echo yes
set "A=before"
if 1==1 (
set /p A=<answer.txt
echo percent: %A%
echo bang: !A!
)Output
percent: before bang: yes
Not clearing the variable. Because empty input does not change the variable, a loop that asks again keeps the previous answer. Run set "VAR=" before each prompt and test with if not defined VAR.
Special characters. Input such as a & b is stored literally, but echo %VAR% then runs b as a second command. Quote the expansion or use delayed expansion, which does not re-parse the value. See setlocal EnableDelayedExpansion and was unexpected at this time for the errors that unquoted values cause.
Checking the result. ERRORLEVEL is 1 after empty input, but if errorlevel 1 is true for any value of 1 or more, so test the variable itself rather than the exit code; checking ERRORLEVEL explains the comparison rules.
FAQ
Why does set /p inside an if or for block show the old value?
cmd expands %VAR% when it parses the whole parenthesised block, before set /p runs. Enable delayed expansion with setlocal EnableDelayedExpansion and read the value as !VAR! inside the block.
How do I read every line of a file instead of the first one?
set /p only reads one line. Use for /f with usebackq and a quoted file name to loop over all lines, or redirect a parenthesised block of several set /p commands to read the first few lines in order.
Can set /p hide a password while it is typed?
No. cmd has no option to mask input; the typed characters are echoed. Use PowerShell Read-Host -AsSecureString when the input must not appear on screen.