Skip to content

/flags/cmd/set-p-read-input

set /p: read user input or the first line of a file in a batch file

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
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.

cmd
set "ANSWER="
set /p "ANSWER=Continue? [y/n] "
if /i "%ANSWER%"=="y" echo continuing

Behaviour

cmd
> 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 line

Output

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

CaseResult
User presses Enter without typingvariable keeps its previous value, ERRORLEVEL 1
set "VAR=" firstvariable is undefined after empty input; test with if not defined VAR
Input with spacesstored as typed, including spaces
Input with & | > <stored as text; quote it when you use it: echo "%VAR%"
set /p VAR=<filefirst 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:

cmd
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.

Sources