我正在尝试编写一个批处理脚本,提示用户输入目录,并将多个文件从此目录复制到另一个目录。为此,我有一个简单的循环,使用标签和set /p
进行输入。问题是按ctrl+c
试图摆脱这个循环并不总是有效。
:checkloop
@set /p READMEPATH=Please enter the location of readme.txt:
@if not exist "%READMEPATH%\README.txt" goto somethingmissing
@goto allfound
:somethingmissing
@echo Can't find readme in directory "%READMEPATH%"
@goto checkloop
:allfound
@echo Okay, found
示例输出类似于
Please enter the location of readme.txt:
Can't find readme in directory ""
Please enter the location of readme.txt: ^CCan't find readme in directory ""
Please enter the location of readme.txt: ^CCan't find readme in directory ""
Please enter the location of readme.txt: ^CCan't find readme in directory ""
Please enter the location of readme.txt: ^CCan't find readme in directory ""
Please enter the location of readme.txt: ^CCan't find readme in directory ""
Please enter the location of readme.txt: ^CTerminate batch job (Y/N)? y
重复按下ctrl + c,就像我按下回车一样,脚本继续运行,直到它最终运行。所需的尝试次数是可变的;有时它会立即起作用,有时2-3次,很少需要7次以上。
操作系统是Windows 10。
答案 0 :(得分:2)
您可以检查是否定义了READMEPATH。
:checkloop
set "READMEPATH="
set /p READMEPATH=Please enter the location of readme.txt:
if not defined READMEPATH exit /b
但是,这无法检测到按空格键CTRL-C和ENTER之间的区别。
答案 1 :(得分:1)
这是基于Dave Benham编写的getKey 1.3版,最初发布于Read key presses via REPLACE - New functions :getKey, :getAnyKey, :getMaskedInput
更复杂的批处理,但作为概念证明,它区分CTRL + C和ENTER。
@echo off
setlocal
for /F %%# in ('forfiles /m "%~nx0" /c "cmd /c echo 0x03"') do set "CTRLC=%%#" & rem capture CTRL-C char
for /F %%# in ('copy /Z "%~dpf0" NUL') do set "CR=%%#" & rem capture carriage return char
for /F %%# in ('"prompt $H&for %%@ in (1) do rem"') do set "BS=%%#" & rem capture backspace char
for /F "tokens=1,2 delims=#" %%# in ('"prompt #$H#$E# & echo on & for %%@ in (1) do rem"') do set "DEL=%%#" & rem capture DEL char
:checkloop
cls & set "READMEPATH="
<nul set/P "=Please enter the location of readme.txt: "
:getPath
call :getKey key
if "%key%" equ "%CTRLC%" exit/B & rem or whatever you wanna do
if "%key%" equ "%CR%" goto:done
if "%key%" equ "%BS%" (
<nul set/P=%DEL%
set "READMEPATH=%READMEPATH:~0,-1%"
) else (
<nul set/P=%key%
set "READMEPATH=%READMEPATH%%key%"
)
goto getPath
:done
if not defined READMEPATH exit/B
@if not exist "%READMEPATH%\README.txt" goto somethingmissing
@goto allfound
:somethingmissing
echo(&echo( Can't find readme in directory "%READMEPATH%"
pause
@goto checkloop
:allfound
@echo Okay, found
endlocal
exit/B
::getKey KeyVar [ValidVar]
::
:: Read a keypress representing a character between 0x00 and 0xFF and store the
:: value in variable KeyVar. Null (0x00), LineFeed (0x0A), and Carriage Return
:: (0x0D) will result in an undefined KeyVar. On Windows 10, Ctrl-Z (0x1A) will
:: also result in an undefined KeyVar. The simplest way to get an undefined
:: KeyVar is to press the [Enter] key.
::
:: The optional ValidVar variable defines the values that will be accepted.
:: If not given or not defined, then all characters are accepted. If given
:: and defined, then only characters within ValidVar are accepted. The first
:: character within ValidVar should either be 0, meaning ignore undefined KeyVar,
:: or 1, meaning accept undefined KeyVar. The remaining characters represent
:: themselves. For example, a ValidVar value of 0YNyn will only accept upper
:: or lower case Y or N. A value of 1YNyn will additionally accept [Enter] etc.
::
:: Any value (except null) may be entered by holding the [Alt] key and pressing
:: the appropriate decimal code on the numeric keypad. For example, holding
:: [Alt] and pressing numeric keypad [1] and [0], and then releasing [Alt] will
:: result in a LineFeed.
::
:: The only way to enter a Null is by holding [Ctrl] and pressing the normal [2]
::
:: An alternate way to enter control characters 0x01 through 0x1A is by holding
:: the [Ctrl] key and pressing any one of the letter keys [A] through [Z].
:: However, [Ctrl-A], [Ctrl-F], [Ctrl-M], and [Ctrl-V] will be blocked on Win 10
:: if the console has Ctrl key shortcuts enabled.
::
:: This function works properly regardless whether delayed expansion is enabled
:: or disabled.
::
:: :getKey version 1.3 was written by Dave Benham, and originally posted at
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=7396
::
:: This work was inspired by posts from carlos and others at
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=6382
::
:getkey
set "%1="
setlocal disableDelayedExpansion
for /f skip^=1^ delims^=^ eol^= %%A in (
'replace.exe ? . /u /w'
) do for /f delims^=^ eol^= %%B in ("%%A") do (
endlocal
if "%%B" equ "" (set "%1=^!") else set "%1=%%B"
)
setlocal enableDelayedExpansion
if "!%2!" neq "" (
if not defined %1 if "!%2:~0,1!" equ "0" (endlocal&endlocal&goto :getKey) else exit /b
set "getKey.key=!%1!"
set "mask=!%2:~1!"
if not defined mask endlocal&endlocal&goto :getKey
if "!getKey.key!" equ "=" (
set "test=a!mask!"
for /f "delims=" %%A in ("!test!") do if /i "!test:%%A=%%A!" equ "!test!" endlocal&endlocal&goto :getKey
)
for /f delims^=^ eol^= %%A in ("!getKey.key!") do if "!mask:*%%A=!" equ "!mask!" endlocal&endlocal&goto :getKey
)
exit /b