Batch file with choosing Y/N - batch-file

Please help, I'm a beginner and I need to create batch-file to delete log-files. But before delete I need to ask user to delete the last log-file or all log-files.
I tried to implement it like:
set /P PARAM_VALUE=Remove only the last log file?(Y/N)?
if /I "%PARAM_VALUE%"=="y" goto DeleteLast
if /I "%PARAM_VALUE%"=="n" goto DeleteAll
But in this case I can enter any values, I need to avoid an others character except Y,y,N,n.
Thx.

One of solutionÑ– in this case is using the CHOICE command.
This tool allows users to select one item from a list of choices and returns the index of the selected choice.
Syntax: CHOICE [ /C choices ] [ /N ] [ /CS ] [ /T timeout /D choice ] [ /M text ]
Parameter List:
/C choices Specifies the list of choices to be created. Default list for English versions is YN
/N Hides the list of choices in the prompt. The message before the prompt is displayed and the choices are still enabled.
/CS Enables case-sensitive choices to be selected. By default, the utility is case-insensitive. Note: DOS and NT Resource Kit versions use /S instead
/T timeout The number of seconds to pause before a default choice
is made. Acceptable values are from 0 to 9999.
If 0 is specified, there will be no pause and the default choice is selected.
Note: DOS and NT Resource Kit versions use /T:default,timeout instead.
/D default Specifies the default choice after timeout seconds.
Character must be in the set of choices specified by /C option and must also specify timeout with /T.
Note: DOS and NT Resource Kit versions use /T:default,timeout instead.
/M text Specifies the message to be displayed before the prompt.
If not specified, the utility displays only a prompt.
For your problem try to use something like:
choice /C:YN /M:"Remove only the last log file? [YN]"
IF ERRORLEVEL ==1 GOTO DeleteLast
IF ERRORLEVEL ==2 GOTO DeleteAll
GOTO next
:DeleteAll
rem delete all
:DeleteLast
rem delete last
:next
rem continue work with Batch file

You can just catch all other inputs like this:
:CONFIRM
if /i "%PARAMVALUE%"=="y" goto DeleteLast
if /i "%PARAMVALUE%"=="n" goto DeleteAll
echo Please enter only Y/y or N/n!
ping localhost -n 2 >nul
goto CONFIRM
I used this too for my own scripts and it works wonderfully and is super easy!

The delete command already offers a prompt N/y
EDIT
del /p
type del /? in console for more information
UPDATE
you can test with this example:
#echo off
SETLOCAL
Echo:
Echo /!\ Creating a bunch of empty files /!\
echo Press any key to continue or CTRL-C to exit...
Pause>nul
for /L %%A in (1,1,4) do (copy /y NUL _temp_file_%%A.ext)
Echo:
Echo /!\ Deleting a bunch of empty files with command prompt /!\
echo Press any key to continue or CTRL-C to exit...
Pause>nul
del /p "_temp_file_?.ext"
Echo:
Pause>nul|(echo Press any key to exit...)

Related

How to automatically input single letter/number in batch

I'm finishing off my program, and I've got a basic menu:
echo [1] - New Log Entry
echo [2] - Read Log Entry
echo [3] - Clear Log
echo [4] - Exit
set /p menu=Number:
if %menu%==1 goto NewLog
if %menu%==2 goto Readlog
:::and so on
But I want it to be so that when you type in one of the numbers, it automatically enters the number they put.
I think I've seen it done before but I'm not too sure.
The command CHOICE can be used for taking one of predefined options.
#echo off
:Menu
cls
echo/
echo [1] - New log entry
echo [2] - Read log entry
echo [3] - Clear log
echo [4] - Exit
echo/
choice /C 1234 /N /M "Your choice: "
echo/
if errorlevel 4 goto :EOF
if errorlevel 3 goto ClearLog
if errorlevel 2 goto ReadLog
rem User has taken first choice as being the only remaining choice.
echo Creating new log entry ...
echo/
pause
goto Menu
:ReadLog
echo Reading log entry ...
echo/
pause
goto Menu
:ClearLog
echo Clearing log ...
echo/
pause
goto Menu
The usage of CHOICE is much better than set /P variable=prompt text for such tasks as the user must press one of the offered keys and execution immediately continues once an offered key is hit by the batch file user. set /P gives the user the freedom to enter anything from not entering anything at all up to a very long string containing characters which might result in a syntax error on evaluation of the environment variable value if not extra code is written to make sure that batch file works even for any invalid user input.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
choice /?
cls /?
echo /?
goto /?
if /?
pause /?
See also the web pages:
Microsoft's command-line reference
SS64.com - A-Z index of the Windows CMD command line
Testing for a Specific Error Level in Batch Files (Microsoft support article)
What are the ERRORLEVEL values set by internal cmd.exe commands? (Stack Overflow topic)
ECHO. FAILS to give text or blank line - Instead use ECHO/ (DosTips forum topic)

How to exit a user input loop in batch?

Well I have a simple for loop to take user input and creat a file with this input, then ask for the next input and create "file2" etc., but I can't seem to figure out how my user can quit the loop with a certain input (maybe "exit" or "end").
setlocal enabledelayedexpansion
set x=1
:runName
set /p names="Enter header for file !x!:"
for %%a in (%names%) do (>>file!x!.txt (echo %%~a) set /a x+=1)
if !names!=end goto:eof else goto:runName
:eof
echo press any key to close
pause>nul
Ps. Sorry for the poor formatting, I cant figure how to enter my code in the grey field from my phone and dont have a computer at the moment.
I'm not quite shure why the input prompt says header.
Here is my best guess what you may have meant:
#Echo off
setlocal enabledelayedexpansion
set x=1
:runName
Set "names="
set /p names="Enter header for file%x%:"
if not defined names goto :end
if /I "%names%" Equ "end" goto :end
(
for %%a in (%names%) do (echo:%%~a)
) >file!x!.txt
set /a x+=1
goto :runName
:end
echo press any key to close
pause>nul
Running
Enter header for file1:anton bertha caesar
Enter header for file2:anchorage berlin
Enter header for file3:END
press any key to close
File content
> type file*.txt
file1.txt
anton
bertha
caesar
file2.txt
anchorage
berlin
I can't seem to figure out how my user can quit the loop
If you'll allow a suggestion, mine would be don't do that.
Almost any batch script is best written to accept command-line options and files as input. Once you trap the user into providing input interactively -- anything more than Y or N, and even that's a nuisance -- you're putting him in a bad spot. He can't re-run your script without going through the tedium again. He can't use tab completion, or pick from a list. He's trapped in a user-interface element that hasn't been improved in 30 years, and wasn't very good then.
I don't know what to suggest specifically. The example you provide is so trivial it would be easier to provide the file directly using Notepad than to create it with a script. Then you might want a verification script to make sure the provided input file is valid.
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
for /f "SKIP=0 EOL=; TOKENS=* DELIMS=" %%i in ('dir /b c:\windows\*.* ^|FIND /i *.exe') do (
CHOICE /D N /T 5 /C YN /M "Please pre Y to exit"
IF !ERRORLEVEL!==1 GOTO :END
IF !ERRORLEVEL!==2 ECHO CONTINUE
timeout 5
#echo %%i
)
:END
ENDLOCAL

Call batch within batch?

How do I call multiple batch files within a single batch? When I try it always goes to the same one or none at all and closes window.
#echo off
:MENU
title MENU0
Echo 1 - Select Menu 1
Echo 2 - Select Menu 2
Echo 0 - Exit
Echo.
SET /P choice=Type the number or letter of task you want, then press ENTER:
IF %choice%==1 GOTO 1
IF %choice%==2 GOTO 2
IF %choice%==0 EXIT
:1
call %userprofile%\desktop\\Menu1.bat
:2
call %userprofile%\desktop\Menu2.bat
There are several issues with provided batch code in question.
The first one is that after processing of the batch file called with command CALL finished, the processing of current batch file continues with the next command respectively line, except the called batch file contains itself the command EXIT without parameter /B as in this case the command processor terminates itself independent on calling hierarchy.
For details about CALL behavior see answers on:
How to call a batch file in the parent folder of current batch file?
In a Windows batch file, can you chain-execute something that is not another batch file?
The second issue is that folder path assigned to environment variable USERPROFILE could contain 1 or more spaces (default on Windows 2000/XP, possible on later Windows versions depending on user name). Therefore always enclose a string referencing USERPROFILE or USERNAME in double quotes.
The third and most difficult to handle issue is that the user of a batch file on prompt with set /P has the freedom to enter anything and not just what the writer of the batch file suggests.
For example
SET /P choice=Type the number or letter of task you want, then press ENTER:
IF %choice%==1 GOTO 1
results in an exit of batch processing caused by a syntax error if the batch user hits just RETURN or ENTER without entering anything at all and the environment variable choice is not already defined with a useful string because in this case the next line to process by command processor is:
IF ==1 GOTO 1
It is good practice to define the environment variable with a default value before set /P as this value is kept when the batch user just hits RETURN or ENTER.
A batch user has also the freedom on using set /P to enter anything including syntax critical characters like " or < or | or > and others by mistake or intentionally (for breaking batch processing by a syntax error).
Therefore it is in general better for menus in batch files to use the command choice (Microsoft article) because then the batch user can enter only what the writer of the batch file offers. But CHOICE is available only by default for Windows Server 2003 and later Windows. And there are different versions of choice (SS64 article with additional information) with a different set of options. So it depends on which Windows version(s) the batch file is designed for if CHOICE can be used at all.
It is also not good to name an environment variable or a label like a command although possible. Therefore choice is not a good name for an environment variable.
Here is a commented batch file with a code which avoids all those issues.
#echo off
:MainMenu
setlocal EnableDelayedExpansion
title MENU0
cls
echo 1 - Select Menu 1
echo 2 - Select Menu 2
echo 0 - Exit
echo.
rem Define 0 as default value in case of user just hits RETURN or ENTER.
set "UsersChoice=0"
set /P "UsersChoice=Type the number or letter of task you want, then press ENTER: "
rem Has the user really entered just one of the offered characters?
rem There must be nothing to process if the user has entered just 0
rem or 1 or 2. Otherwise the user's choice was either by mistake or
rem intentionally entered wrong. The string entered by the user is
rem referenced with delayed expansion to avoid an exit of batch
rem processing in case of user entered a syntax critical character.
for /F "tokens=1 delims=012" %%I in ("!UsersChoice!") do (
endlocal
goto MainMenu
)
rem Now it is safe to reference the variable value without usage of delayed
rem expansion as a syntax error caused by user input can't occur anymore.
rem The entered string does not contain any not expected character. But
rem it is possible that for example 11 was entered by mistake instead
rem of just 1. The entered string should have a length of 1 character.
if not "%UsersChoice:~1,1%" == "" (
endlocal
goto MainMenu
)
rem Exit this batch processing on user entered 0. Previous environment is
rem automatically restored by command processor by an implicit endlocal.
if "%UsersChoice%" == "0" exit /B
rem Restore previous environment as the called batch files are most
rem likely written for using standard command environment with delayed
rem expansion not enabled (exclamation mark interpreted different).
rem The current value of local environment variable must be passed
rem to previous environment for usage on GOTO command.
endlocal & goto Menu%UsersChoice%
:Menu1
call "%USERPROFILE%\Desktop\Menu1.bat"
goto MainMenu
:Menu2
call "%USERPROFILE%\Desktop\Menu2.bat"
goto MainMenu
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
cls /?
echo /?
endlocal /?
exit /?
for /?
goto /?
rem /?
set /?
setlocal /?
title /?
For meaning of & in line endlocal & goto Menu%UsersChoice% see answer on Single line with multiple commands using Windows batch file.
I tried your code and what I found was that when the input was 1 both :1 and :2 are executed but when the input is 2 only :2 is executed. To fix this you need to specify the end of :1 using Exit or another goto.
You might see that none the batches are being executed IF you do not put a pause in the end of your script. They would be executed but the result might just flash out of the screen.
Also I do not understand why have you used \\Menu1.batand not \Menu1.bat in
:1
call %userprofile%\desktop\\Menu1.bat
The final working code for me-
#echo off
:MENU
title MENU0
Echo 1 - Select Menu 1
Echo 2 - Select Menu 2
Echo 0 - Exit
Echo.
SET /P choice=Type the number or letter of task you want, then press ENTER:
IF %choice%==1 GOTO 1
IF %choice%==2 GOTO 2
IF %choice%==0 EXIT
:1
call yourpathhere\Menu1.bat
pause
GOTO cont
:2
call whatsoever\Menu2.bat
pause
GOTO cont
:cont
exit
That should fix your problem.
Hope I helped.
I may not be a pro, but I could help you!
I always add extra code on my games in order to avoid bugs, like this:
set /p letter=
if %letter% == 1 goto nocheck1
if %letter% == 2 goto nocheck2
if %letter% == 3 exit
:nocheck1
if %letter% == 1 goto saves
:nocheck2
if %letter% == 2 goto howtoplay
Maybe it could work on your problem!
I might have the code to do it:
#echo off
cls
:menu
cls
echo 1. Open Batch 1
echo 2. Open Batch 2
set /p test=Enter number here ----->
if %test% == 1 goto check1
if %test% == 2 goto check2
Edit the "Batch file name" text with your location of your batch file.
:check1
if %test% == 1 start C:\Users\%username%\Desktop\(batch file name).bat
:check2
if %test% == 2 start C:\Users\%username%\Desktop\(batch file name).bat
If there's still any errors with my code, let me know.
Hope this helps your problem!
Use cd to go to the location of batch file. For example:
rem myscript
echo calling batch file
cd demo\desktop\script
execute.bat
echo done
After the execution of that batch, control will return to the next line of your script.
Use "Start" instead of "Call" like so,
#echo off
:MENU
title MENU0
Echo 1 - Select Menu 1
Echo 2 - Select Menu 2
Echo 0 - Exit
Echo.
SET /P choice=Type the number or letter of task you want, then press ENTER:
IF %choice%==1 GOTO 1
IF %choice%==2 GOTO 2
IF %choice%==0 EXIT
:1
start %userprofile%\desktop\\Menu1.bat
:2
start %userprofile%\desktop\Menu2.bat
Try This:
#echo off
:MENU
title MENU0
Echo 1 - Select Menu 1
Echo 2 - Select Menu 2
Echo 0 - Exit
Echo.
SET /P choice=Type the number or letter of task you want, then press
Enter:
IF %choice%==1 GOTO 1
IF %choice%==2 GOTO 2
IF %choice%==0 EXIT
:1
cd users
cd %userprofile%
cd desktop
:: call Menu1.bat or use: start Menu1.bat
:: exit
:2
cd users
cd %userprofile%
cd desktop
:: call Menu2.bat or use: start Menu2.bat
:: exit
start "" C:\location\of\file\file.bat
This opens a new window, and as long as you have more commands to follow, the previous file that is calling the new one will still run along with this one.

Terminate current command and move to next command in bat file

I've created a batch file
#echo off
Mkdir c:\asp
Copy * c:\asp\
Cd/
CD c:\asp
Dir
Pause
If I want to terminate the copy command and move to dir command how can I do so?
Since CTRL + C will terminate overall script and not a single command , I suggest to launch Copy command in a separate CMD window without /WAIT and then use label to go to your desired command ,
#echo off
Mkdir c:\asp
START Copy * c:\asp\
GOTO SABIRLABEL
Cd/
CD c:\asp
:SABIRLABEL
Dir
Pause
You can then use CTRL + C in second window to terminate copy if its long running process.
Also you can make GOTO conditional on some variable value if you don't always wish to skip those two commands.
Hope it helps !!
I think you could use "CHOICE" (available under DOS in Win 8.1)
#echo off
Mkdir c:\asp
HERE goes CHOICE///// etc...
Copy * c:\asp\
Cd/
CD c:\asp
Dir
Pause
Example:
OPEN DOS BOX...
TYPE CHOICE /?
See this...
C:\Windows\system32>choice /?
CHOICE [/C choices] [/N] [/CS] [/T timeout /D choice] [/M text]
Description:
This tool allows users to select one item from a list
of choices and returns the index of the selected choice.
NOTE:
The ERRORLEVEL environment variable is set to the index of the
key that was selected from the set of choices. The first choice
listed returns a value of 1, the second a value of 2, and so on.
If the user presses a key that is not a valid choice, the tool
sounds a warning beep. If tool detects an error condition,
it returns an ERRORLEVEL value of 255. If the user presses
CTRL+BREAK or CTRL+C, the tool returns an ERRORLEVEL value
of 0. When you use ERRORLEVEL parameters in a batch program, list
them in decreasing order.
Examples:
CHOICE /?
CHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."
CHOICE /T 10 /C ync /CS /D y
CHOICE /C ab /M "Select a for option 1 and b for option 2."
CHOICE /C ab /N /M "Select a for option 1 and b for option 2."

BATCH program crashes after goto command

This code is part of a chat program that I am currently working on. The 'else' part of my program is the one that doesn't work. The program quits instead of going to :home
:join
cls
if not exist "C:/Users/Public/room.cmd" (
echo No room has been found.
echo.
set /p choiceretry=Do you want to retry? y/n
if "%choiceretry%"=="y" goto join
if "%choiceretry%"=="n" goto home
) else (
cls
"C:/Users/Public/room.cmd"
echo A room has been found.
pause >nul
echo Joining
set roomjoined=1
echo %roomjoined%
goto home
)
:home
echo this finally works
pause
I have tried changing the code several times starting from 'echo Joining'
Anyone know why cmd quits?...
:) :) :)
Thanks in advance
The problem is the way you run room.cmd; you must use call to return from it:
call "C:/Users/Public/room.cmd"
Otherwise, execution will not return from room.cmd to the original batch file that ran it.
Hint: Consider to use choice instead of set /P for Y/N decisions.
Firstly, please don't left justify your code blocks. It's much easier to read code that's properly indented.
Secondly, when retrieving values within a code block, you need delayed expansion. See setlocal /? in a cmd prompt for more information. This is the reason for the unexpected behavior. Your variables retrieved within the same parenthetical code block in which they were set won't contain the values you expect unless you retrieve them with delayed expansion syntax. As an alternative, you could use the choice command and if errorlevel, which would result in a bit nicer user experience I think.
Thirdly, when testing user input, you should use the /i switch in your if statements for case-insensitivity. This isn't relevant if using choice / if errorlevel though.
Fourthly, Windows paths use backslashes, not forward slashes.
I'd fix it this way:
#echo off
setlocal
:join
cls
if errorlevel 1 set /P "=Retrying... "<NUL
if not exist "C:\Users\Public\room.cmd" (
echo No room has been found.
echo.
choice /c yn /n /m "Do you want to retry? [y/n] "
if errorlevel 2 goto home
goto join
) else (
"C:\Users\Public\room.cmd"
echo A room has been found.
pause >nul
echo Joining
set roomjoined=1
)
:home
echo this finally works
pause

Resources