1

I have a batch file to help clients do automated backup of their files, however it's not editing friendly to them, so I plan to make the clients input a letter for the destination drive of their backup.

The problem is, I do not know how to limit their input to only one characters and only a-z

I have read this resource > Batch File input validation - Make sure user entered an integer . But still can't figure out any solution

The question is, do we really can limit the input length and the validation thing? are there any reference can use on this matter?

here is my code

:init
@echo off
color 02

REM -- set vars
set tgl=%DATE:~0,2%
set bln=%DATE:~-7,2%
set thn=%DATE:~-4,4%
set jam=%TIME:~0,2%
if "%time:~0,1%"==" " set jam=0%TIME:~1,1%
set menit=%TIME:~3,2%
set detik=%TIME:~6,2%



echo Under which drive will you save the backup? ( one letter only, a-z )
set /p drive=
pause
cls
:stopsvc
net stop svc01
cls
echo stop service   [OK]
echo copy files     [ ]
echo start service  [ ]
echo archiving  [ ]
echo.
REM -- start backup
echo.
:copy
echo copying ...
xcopy /e /y c:\docs %drive%:\data\docs\
cls
echo stop service   [OK]
echo copy files     [OK]
echo start service  [ ]
echo archiving  [ ]
echo.
echo.
:startsvc
echo starting MySQL service...
net start svc01
if errorlevel = 1 goto svcfail
echo.
echo done
cls
echo stop service   [OK]
echo copy files     [OK]
echo start service  [OK]
echo archiving  [ ]
echo.
echo.
echo backup successfully created
echo now archiving ...
echo.
:archive
cd "%drive%:\data"
ren "docs" "BACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%"
echo archiving - OK
cls
echo stop service   [OK] > "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo copy files     [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo start service  [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo archiving  [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo. 
echo.
echo buhbye
echo copyright(c) [SC] 2010-2011
pause
goto eof

:svcfail
echo cannot start svc01 service > "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo start it manually through services.msc >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo.
echo.
echo stop service   [OK]
echo copy files     [OK]
echo start service  [FAIL]
echo archiving  [ ]
pause
goto archive1
:archive1
cd "%drive%:\data"
ren "docs" "BACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%"
echo archiving - OK
cls
echo stop service   [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo copy files     [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo start service  [FAIL] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo archiving  [OK] >> "logBACKUP-[%jam%.%menit%]-%tgl%-%bln%-%thn%.txt"
echo.
echo.
echo all done~!
pause
goto eof



:eof
exit
Community
  • 1
  • 1
skeith
  • 83
  • 1
  • 4
  • 11

4 Answers4

4

The following uses basic cmd syntax. It will loop until user enter a single lowercase character.

:choice
set /p choice=Under which drive will you save the backup? ( one letter only, a-z )
if not "%choice:~1,1%"=="" goto choice
if "%choice%" lss "a" goto choice
if "%choice%" gtr "z" goto choice
set drive=%choice%
Gilles Arcas
  • 2,692
  • 2
  • 18
  • 13
  • your solution is simpler, love it. But due to the urgency of the script, I have to made my script fixed without user input. However, I plan to make another one with user input – skeith Jan 09 '12 at 03:29
  • This solution as written is case sensitive - Upper case letters won't work, but they probably should. – dbenham Jan 12 '12 at 16:34
  • @Gilles Arcas Can you break down how`"%choice:~1,1%"==""` limits the input to 1 character? Also, it sounds like the `if` statements are saying `if choice is less than "a" and greater than "z", try again.` How does this allow adding a drive letter between a and z? And @dbenham, add `IF /I` to make it case insensitive. – host_255 Mar 08 '17 at 23:27
1

There is no way to do that with the original BATCH commands; however, you may use a third party program. For example, the Batch file below create GETKEY.COM file:

@ECHO OFF
REM CREATE THE GETKEY.COM AUXILIARY FILE
(
ECHO E100
ECHO B4 08 CD 21 B4 4C CD 21
ECHO RCX
ECHO 8
ECHO W
ECHO Q
) | DEBUG GETKEY.COM > NUL

You must have DEBUG.COM in order for this to work. GETKEY read a key and return its ASCII code in ERRORLEVEL, the key read is NOT echoed to the screen. You must manipulate the value returned to check that is into the desired range, and then convert it to the equivalent letter:

set aLetter=97
set zLetter=122
set lowcaseLetters=a b c d e f g h i j k l m n o p q r s t u v w x y z

REM Read a key and check that it is in range
:readKey
getkey
set key=%errorlevel%
if %key% LSS %aLetter% goto readKey
if %key% GTR %zLetter% goto readKey

REM Convert ASCII code to an index between 1 and 26
set /A index=key-aLetter+1

REM Get the letter and echo it in the screen
for /F "tokens=%index%" %%a in ("%lowcaseLetters%") do set letter=%%a
echo %letter%

You may even process function and special keys this way...

Aacini
  • 65,180
  • 12
  • 72
  • 108
  • where can I get this "debug.com" ? and what is those echo commands do? any reference on that? – skeith Dec 13 '11 at 06:30
  • It is the code of an executable program originally written in assembler language (8 bytes long). You may get DEBUG from this site, but check first that isn´t already installed in your computer: http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/pkgs/debugx.zip – Aacini Dec 13 '11 at 17:21
  • how can i check whether i have DEBUG or not? – skeith Dec 14 '11 at 03:01
  • Type: DEBUG at your command prompt; if DEBUG starts, type Q and Enter to quit. – Aacini Dec 14 '11 at 06:19
1

If you are using Vista or later, you can use the CHOICE command (type 'CHOICE /?' for documentation) By default, CHOICE is case insensitive, which I think is a good thing for your situation.

setlocal enableDelayedExpansion
set "choices=abcdefghijklmnopqrstuvwxyz"
echo Under which drive will you save the backup? ( one letter only, a-z )
choice /c %choices% /n
set /a "n=%errorlevel%-1"
set "drive=!choices:~%n%,1!"

Here is a variation of Giles Arcas strategy of post entry validation that allows both upper and lower case. It is also a bit more robust in that it handles empty strings properly. This should work on XP and later.

setlocal enableDelayedExpansion
set "choices=abcdefghijklmnopqrstuvwxyz"
:select
echo Under which drive will you save the backup? ( one letter only, a-z )
set "drive="
set /p "drive="
for /l %%N in (0 1 25) do if /i "!choices:~%%N,1!"=="%drive%" goto :continue
goto :select
:continue

Here is another variation that uses a FINDSTR regular expression to validate the entry

setlocal enableDelayedExpansion
:select
echo Under which drive will you save the backup? ( one letter only, a-z )
set "drive="
set /p "drive="
echo !drive!|findstr /r /i "^[abcdefghijklmnopqrstuvwxyz]$" >nul || goto :select

The delayed expansion is advised in case the user enters a string like "&"&

dbenham
  • 127,446
  • 28
  • 251
  • 390
0

You may use ReadFormattedLine subroutine for all kind of formatted input. For example, the command below read just one letter:

call :ReadFormattedLine drive="L" /M "Under which drive will you save the backup? "

This subroutine is written in pure Batch so it does not require any additional program, and it allows several formatted input operations, like read passwords. In previous example, the subroutine automatically continue after the user press a letter, so it does not require Enter key. You may download ReadFormattedLine subroutine from Read a line with specific format.

Aacini
  • 65,180
  • 12
  • 72
  • 108