I am using a Batch File to search a list of functions for an exact match, wondering if its possible to do a key word search, so right now i have to type "open cmd"
(variations on spacing and capital letters are accounted for)
Id like to switch it over to a system that can look for "cmd" and perform the action so "hey, open cmd please" would yield the same result as the old system
Old system:
setlocal
:: /STARTUP
set speech=start scripts\nircmd.exe speak text
cls
:begin
set TALK=TypeSomething
SET /P TALK=
set TALK=%TALK:?=%
call :%TALK: =% 2>NUL
if %errorlevel% equ 0 goto begin
exit /B 0
:unknown
echo Old function no longer supported
:opencmd
:BOSopencmd
:cmd
echo Command Prompt has now been opened in a new window, sir.
%speech% "Command Prompt has now been opened in a new window, sir."
start scripts\cmd.bat
exit /B 0
It is based of a chat bot i tried to make in middle school so the %speech% is not an important item, i can add that and the echo later. I just need a system that works like the old one if possible. The other i can have any number of functions with
:cmd
start cmd
Exit /B 0
or
:reddit
start http://www.reddit.com/
exit /B 0
at these need to be able to stack. I can transition to having scripts for each function in a separate batch files if needed. Ive tried trying findstr but it wasn't giving the desired results. Ive exhausted my knowledge on what i might be able to do but I've come up short lol, If you are having trouble understanding what i'm asking don't hesitate to let me know
I learn by taking things apart so partial code is appreciated but will not be much help until after I've figured out what does what .
Here's a sample of how you might approach it using ECHO, FINDSTR, and CALL (This is a modified example from the original per your request to be able to process multiple keywords):
#echo off
set TST_FNDFLG=FALSE
set TST_USRANS=
set /P TST_USRANS=Enter keywords:
if "%TST_USRANS%" == "" goto ENDIT
echo %TST_USRANS% | findstr /i "CMD" >NUL 2>&1
if ERRORLEVEL 1 goto TRYRED
call :DOCMD
:TRYRED
echo %TST_USRANS% | findstr /i "REDDIT" >NUL 2>&1
if ERRORLEVEL 1 goto TRYGOO
call :DORED
:TRYGOO
echo %TST_USRANS% | findstr /i "GOOGLE" >NUL 2>&1
if ERRORLEVEL 1 goto TRYEND
call :DOGOO
goto TRYEND
:DOCMD
if [%TST_FNDFLG%] == [FALSE] echo.
echo CMD was found in "%TST_USRANS%"
set TST_FNDFLG=TRUE
goto :EOF
:DORED
if [%TST_FNDFLG%] == [FALSE] echo.
echo REDDIT was found in "%TST_USRANS%"
set TST_FNDFLG=TRUE
goto :EOF
:DOGOO
if [%TST_FNDFLG%] == [FALSE] echo.
echo GOOGLE was found in "%TST_USRANS%"
set TST_FNDFLG=TRUE
goto :EOF
:TRYEND
echo.
if [%TST_FNDFLG%] == [TRUE] echo No more keywords found
if [%TST_FNDFLG%] == [FALSE] echo Did not find any known keywords
goto ENDIT
:ENDIT
echo.
set TST_USRANS=
set TST_FNDFLG=
I belive i found a nice way to send out a command line to multiple batch windows at once, here is how i see it going:
Using Set with /p allows me to user input a string that i save as message
Exporting it to its own bat file with "Echo set command=%message% >command.bat
Using echo to type out ftp information and then run it with "Ftp -s:upload.txt ftp.example.com
This uploads it to my webhotel where im gonna use a bitadmin.exe to download the file
Then running command.bat and ensuring that if the string %command% isnt the same before it runs the command
It's all working fine and what not, but i feel like my ftp name/password is too exposed to anyone that has the IQ to "Right-Click, Edit" and inspect the code. I've come to the point where i'm trying to make it harder to really get it just by looking at the batch file.
So far i converted my password into HEX and using a fancy batch file convert it back into a string from a batch file i call, and then export it with the ftp connection file. It works all up untill the batch reads the ftp connection file and gets stuck on "requiring password" even though when i check my ftp connection file then the password is correctly typed in the right place, no additional spaces or odd stuff. But it wont work untill i deleted the line and typed it in my self. (The other way that i was considering using a Batch to exe program but that just runs the batch file in the temp folder, everyone knows that) The hex password i use here is just "password"
Code so far:
#Echo Off
:Start
Rem (1)Set/(2)Export Message
Rem (1)
Set /p message=
Rem (2)
Echo set run=%message% >command.bat
Rem (1)Decode Hex/(2)Running hex output/(3)Acces FTP service
Rem (1)
Start HEX.bat 70617373776f7264
Rem (2)
Call CODE.bat
Del /Q CODE.bat
Rem (3)
Echo darkrock> upload.txt
Echo %code%>> upload.txt
Echo asc>>upload.txt
Echo put command.bat>> upload.txt
Echo quit >> upload.txt
Ftp -s:upload.txt ftp.example.com
Goto :Start
The hex converter comes here:
#echo off
setlocal DisableDelayedExpansion
set Caret=^^
set ControlChar={SOH} {STX} {ETX} {EOT} {ENQ} {ACK} {BEL} {BS} {HT} {LF} {VT} {FF} {CR} {SO} {SI} {DLE} {XON}
set ControlChar=%ControlChar% {DC2} {XOFF} {DC4} {NAK} {SYN} {ETB} {CAN} {EM} {SUB} {ESC} {FS} {GS} {RS} {US}
set AsciiChar= !"#$%%&'()*+,-./0123456789:;<=>?
setlocal EnableDelayedExpansion
set AsciiChar=!AsciiChar!#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]!Caret!_`abcdefghijklmnopqrstuvwxyz{^|}~
set AsciiChar=!AsciiChar!€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿
set AsciiChar=!AsciiChar!ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
set HexCode=%1
call :Conversion
echo Hex: %1
echo Dec: %DecimalCode%
echo Ascii: !AsciiCode!
echo Bin: %BinaryCode%
cls
goto :EOF
:Conversion
set DecimalCode=
set AsciiCode=
set BinaryCode=
:ConvertHex
set /A Decimal=0x%HexCode:~0,2%, DecChar=Decimal-32
set DecimalCode=%DecimalCode%%Decimal%,
if %Decimal% lss 32 (
if %Decimal% equ 0 (
set AsciiCode=!AsciiCode!{NUL}
) else (
for /F "tokens=%Decimal%" %%c in ("%ControlChar%") do set AsciiCode=!AsciiCode!%%c
)
) else (
set AsciiCode=!AsciiCode!!AsciiChar:~%DecChar%,1!
)
call :DecToBin
set BinaryCode=%BinaryCode%%Binary%,
set HexCode=%HexCode:~2%
if defined HexCode goto ConvertHex
exit /B
:DecToBin
set Binary=
for /L %%i in (1,1,8) do (
set /A "Bit=Decimal&1, Decimal>>=1"
set Binary=!Bit!!Binary!
)
echo set code=%AsciiCode% >Code.bat
exit /B
Thx in advance! :) It might be me that missed something in the code but i belive i tried by best the last two days compared to being busy with collage.
I'm creating a batch file that will launch when I login to my user account. I followed this tutorial to create a batch file with a menu. It works, however, if the user enters a number that is not listed, I want it to go back to the menu. How would I implement that?
Side note: I understand I could use something more flexible like Powershell, however, I prefer batch files.
Here is what I have so far:
#ECHO OFF
CLS
:MENU
echo Welcome %USERNAME%
echo 1 - Start KeePass
echo 2 - Backup
echo 3 - Exit
SET /P M=Type 1,2,3 then press Enter:
IF %M%==1 GOTO StarKeePass
IF %M%==2 GOTO Backup
IF %M%==3 GOTO :EOF
:StarKeePass
SET keePass="%USERPROFILE%\KeePass\KeePass-2.30\KeePass.exe"
SET kdb="%USERPROFILE%\KeePass\PasswordDatabase\PasswordDatabase.kdbx"
echo I'll start KeePass for You
START "" %keePass% %kdb%
GOTO MENU
:Backup
SET backup="%USERPROFILE%\backup.bat"
call %backup%
GOTO MENU
To build a menu using set /P, I recommend the following changes:
after all the if queries, put a goto :MENU to catch unintended entries;
reset the selection variable by something like set "SELECT=" before the set /P command, because set /P keep the former value of the variable in case the user presses just ENTER;
put quotes "" around the expressions in the if statements to avoid syntax errors in case the variable is empty or it contains some characters that have special meanings (^ & ( ) < > |; the " character still causes problems though);
use the quoted syntax set [/P] "SELECT=anything" to avoid trouble with special characters;
in case letters are queried, add the /I switch to if to force case-insensitive comparison;
if you wish, you could put a cls command after the :MENU label to let the screen be built up every time you return to the menu;
Here is an example that demonstrates what I am talking about:
#echo off
:MENU
cls
echo --- MAIN MENU ---
echo 1 - do something
echo 2 - do something else
echo Q - quit
set "SELECT="
set /P "SELECT=Type 1, 2, or Q <Enter>: "
if "%SELECT%"=="1" GOTO :SOMEWHERE
if "%SELECT%"=="2" GOTO :SOMEWHERE_ELSE
if /I "%SELECT%"=="Q" GOTO :EOF
goto :MENU
:SOMEWHERE
rem do something here...
echo.
echo Print some text.
pause
goto :MENU
:SOMEWHERE_ELSE
rem do something else here...
echo.
echo Print some other text.
pause
goto :MENU
To avoid the above mentioned troubles with the " character, modify the set /P block as follows:
set "SELECT=""
set /P "SELECT=Type 1, 2, or Q <Enter>: "
set "SELECT=%SELECT:"=%"
if "%SELECT%"=="1" GOTO :SOMEWHERE
if "%SELECT%"=="2" GOTO :SOMEWHERE_ELSE
if /I "%SELECT%"=="Q" GOTO :EOF
goto :MENU
How do you check for already existing batch files in batch script?
I'm working on a batch RPG game where you can log in or create an account. I have successfully been able to set up a code that notifies the user when the username has a space in it, and how it can't be used, but I'm stumped at how it could be done to check for a duplicate batch file. For example, I already have a username called "Test", and I would like to make another username called "Test"...
Here is a copy of my code for the no spaces script:
:createuser
echo.
echo What would you like your Username to be?
set /p username1=
set v1f=0
:checkforspaces
set x=!v1f!
set Letter%v1f%=!username1:~%x%,1!
if "!Letter%v1f%!" EQU " " (
echo.
echo.
echo Sorry you cant use spaces in your Username.
pause>nul
goto entergame
)
if NOT "!Letter%v1f%!" EQU "" (
set /a v1f=%v1f%+1
goto checkforspaces
)
echo.
echo What would you like your Password to be?
set /p password1=
goto DATA_VALUES
To check for spaces in var:
echo %var%|find " " >nul
if errorlevel 1 (echo no spaces) else (echo spaces found)
to check whether the filename var exists:
if exist %var%.ext (echo file %var%.ext exists) else (echo file %var%.ext not found)
btw - an easy-peasy game-save routine is
set>%var%.ext
and reload is
for /f "delims=" %%a in (%var%.ext) do set %%a
note that var above can be any variable-name and .ext your chosen file extension.
I have a batch file that automates copying a bunch of files from one place to the other and back for me. Only thing is as much as it helps me I keep accidentally selecting that command off my command buffer and mass overwriting uncommitted changes.
What code would I need for my .bat file to make it output "Are you sure?", and make me type Y before it ran the rest of the file?
If anything other than Y is typed, it should exit execution on that line.
When I call exit, it closes cmd.exe which is not what I want.
You want something like:
#echo off
setlocal
:PROMPT
SET /P AREYOUSURE=Are you sure (Y/[N])?
IF /I "%AREYOUSURE%" NEQ "Y" GOTO END
echo ... rest of file ...
:END
endlocal
try the CHOICE command, e.g.
CHOICE /C YNC /M "Press Y for Yes, N for No or C for Cancel."
There are two commands available for user prompts on Windows command line:
set with option /P available on all Windows NT versions with enabled command extensions and
choice.exe available by default on Windows Vista and later Windows versions for PC users and on Windows Server 2003 and later server versions of Windows.
set is an internal command of Windows command processor cmd.exe. The option /P to prompt a user for a string is available only with enabled command extensions which are enabled by default as otherwise nearly no batch file would work anymore nowadays.
choice.exe is a separate console application (external command) located in %SystemRoot%\System32. File choice.exe of Windows Server 2003 can be copied into directory %SystemRoot%\System32 on a Windows XP machine for usage on Windows XP like many other commands not available by default on Windows XP, but available by default on Windows Server 2003.
It is best practice to favor usage of CHOICE over usage of SET /P because of the following reasons:
CHOICE accepts only keys (respectively characters read from STDIN) specified after option /C (and Ctrl+C and Ctrl+Break) and outputs an error beep if the user presses a wrong key.
CHOICE does not require pressing any other key than one of the acceptable ones. CHOICE exits immediately once an acceptable key is pressed while SET /P requires that the user finishes input with RETURN or ENTER.
It is possible with CHOICE to define a default option and a timeout to automatically continue with default option after some seconds without waiting for the user.
The output is better on answering the prompt automatically from another batch file which calls the batch file with the prompt using something like echo Y | call PromptExample.bat on using CHOICE.
The evaluation of the user's choice is much easier with CHOICE because of CHOICE exits with a value according to pressed key (character) which is assigned to ERRORLEVEL which can be easily evaluated next.
The environment variable used on SET /P is not defined if the user hits just key RETURN or ENTER and it was not defined before prompting the user. The used environment variable on SET /P command line keeps its current value if defined before and user presses just RETURN or ENTER.
The user has the freedom to enter anything on being prompted with SET /P including a string which results later in an exit of batch file execution by cmd because of a syntax error, or in execution of commands not included at all in the batch file on not good coded batch file. It needs some efforts to get SET /P secure against by mistake or intentionally wrong user input.
Here is a prompt example using preferred CHOICE and alternatively SET /P on choice.exe not available on used computer running Windows.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
echo This is an example for prompting a user.
echo/
if exist "%SystemRoot%\System32\choice.exe" goto UseChoice
setlocal EnableExtensions EnableDelayedExpansion
:UseSetPrompt
set "UserChoice="
set /P "UserChoice=Are you sure [Y/N]? "
set "UserChoice=!UserChoice: =!"
if /I "!UserChoice!" == "N" endlocal & goto :EOF
if /I not "!UserChoice!" == "Y" goto UseSetPrompt
endlocal
goto Continue
:UseChoice
%SystemRoot%\System32\choice.exe /C YN /N /M "Are you sure [Y/N]?"
if not errorlevel 1 goto UseChoice
if errorlevel 2 goto :EOF
:Continue
echo So you are sure. Okay, let's go ...
rem More commands can be added here.
endlocal
Note: This batch file uses command extensions which are not available on Windows 95/98/ME using command.com instead of cmd.exe as command interpreter.
The command line set "UserChoice=!UserChoice: =!" is added to make it possible to call this batch file with echo Y | call PromptExample.bat on Windows NT4/2000/XP and do not require the usage of echo Y| call PromptExample.bat. It deletes all spaces from string read from STDIN before running the two string comparisons.
echo Y | call PromptExample.bat results in YSPACE getting assigned to environment variable UserChoice. That would result on processing the prompt twice because of "Y " is neither case-insensitive equal "N" nor "Y" without deleting first all spaces. So UserChoice with YSPACE as value would result in running the prompt a second time with option N as defined as default in the batch file on second prompt execution which next results in an unexpected exit of batch file processing. Yes, secure usage of SET /P is really tricky, isn't it?
choice.exe exits with 0 in case of the user presses Ctrl+C or Ctrl+Break and answers next the question output by cmd.exe to terminate the batch job with N for NO. For that reason the condition if not errorlevel 1 goto UserChoice is added to prompt the user once again for a definite answer on the prompt by batch file code with Y or N. Thanks to dialer for the information about this possible special use case.
The first line below the batch label :UseSetPrompt could be written also as:
set "UserChoice=N"
In this case the user choice input is predefined with N which means the user can hit just RETURN or ENTER (or Ctrl+C or Ctrl+Break and next N) to use the default choice.
The prompt text is output by command SET as written in the batch file. So the prompt text should end usually with a space character. The command CHOICE removes from prompt text all trailing normal spaces and horizontal tabs and then adds itself a space to the prompt text. Therefore the prompt text of command CHOICE can be written without or with a space at end. That does not make a difference on displayed prompt text on execution.
The order of user prompt evaluation could be also changed completely as suggested by dialer.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
echo This is an example for prompting a user.
echo/
if exist "%SystemRoot%\System32\choice.exe" goto UseChoice
setlocal EnableExtensions EnableDelayedExpansion
:UseSetPrompt
set "UserChoice="
set /P "UserChoice=Are you sure [Y/N]? "
set "UserChoice=!UserChoice: =!"
if /I not "!UserChoice!" == "Y" endlocal & goto :EOF
endlocal
goto Continue
:UseChoice
%SystemRoot%\System32\choice.exe /C YN /N /M "Are you sure [Y/N]?"
if not errorlevel 2 if errorlevel 1 goto Continue
goto :EOF
:Continue
echo So you are sure. Okay, let's go ...
endlocal
This code results in continuation of batch file processing below the batch label :Continue if the user pressed definitely key Y. In all other cases the code for N is executed resulting in an exit of batch file processing with this code independent on user pressed really that key, or entered something different intentionally or by mistake, or pressed Ctrl+C or Ctrl+Break and decided next on prompt output by cmd not terminating the batch job.
For even more details on usage of SET /P and CHOICE for prompting user for a choice from a list of options see answer on How to stop Windows command interpreter from quitting batch file execution on an incorrect user input?
Some more hints:
IF compares the two strings left and right of the comparison operator with including the double quotes. So case-insensitive compared is not the value of UserChoice with N and Y, but the value of UserChoice surrounded by " with "N" and "Y".
The IF comparison operators EQU and NEQ are designed primary for comparing two integers in range -2147483648 to 2147483647 and not for comparing two strings. EQU and NEQ work also for string comparisons, but result on comparing strings in double quotes after a useless attempt to convert left string to an integer. EQU and NEQ can be used only with enabled command extensions. The comparison operators for string comparisons are == and not ... == which work even with disabled command extensions as even command.com of MS-DOS and Windows 95/98/ME supported them. For more details on IF comparison operators see Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files.
The command goto :EOF requires enabled command extensions to really exit batch file processing. For more details see Where does GOTO :EOF return to?
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 /?
echo /?
endlocal /?
goto /?
if /?
set /?
setlocal /?
See also:
This answer for details about the commands SETLOCAL and ENDLOCAL.
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
It explains the reason for using syntax set "variable=value" on assigning a string to an environment variable.
Single line with multiple commands using Windows batch file for details on if errorlevel X behavior and operator &.
Microsoft documentation for using command redirection operators explaining the redirection operator | and handle STDIN.
Wikipedia article about Windows Environment Variables for an explanation of SystemRoot.
DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/
The choice command is not available everywhere. With newer Windows versions, the set command has the /p option you can get user input
SET /P variable=[promptString]
see set /? for more info
Here a bit easier:
#echo off
set /p var=Are You Sure?[Y/N]:
if %var%== Y goto ...
if not %var%== Y exit
or
#echo off
echo Are You Sure?[Y/N]
choice /c YN
if %errorlevel%==1 goto yes
if %errorlevel%==2 goto no
:yes
echo yes
goto :EOF
:no
echo no
Here's my go-to method for a yes/no answer.
It's case-insensitive also.
This just checks for the errors given by the input and sets the choice variable to whatever you require so it can be used below in the code.
#echo off
choice /M "[Opt 1] Do you want to continue [Yes/No]"
if errorlevel 255 (
echo Error
) else if errorlevel 2 (
set "YourChoice=will not"
) else if errorlevel 1 (
set "YourChoice=will"
) else if errorlevel 0 (
goto :EOF
)
echo %YourChoice%
pause
You can also use 'Choice' command
#echo off
echo Sure?
CHOICE /C YN
IF %ERRORLEVEL% EQU 1 goto CONTINUE
IF %ERRORLEVEL% EQU 2 goto END
:END
exit
:CONTINUE
echo hi
pause
If you want to the batch program to exit back to the prompt and not close the prompt (A.K.A cmd.exe) you can use "exit /b".
This may help.
set /p _sure="Are you sure?"
::The underscore is used to ensure that "sure" is not an enviroment
::varible
if /I NOT "_sure"=="y" (
::the /I makes it so you can
exit /b
) else (
::Any other modifications...
)
Or if you don't want to use as many lines...
Set /p _sure="Are you sure?"
if /I NOT "_sure"=="y" exit /b
::Any other modifications and commands.
Hope this helps...
Here is a simple example which I use in a backup (.bat / batch) script on Windows 10, which allows me to have different options when making backups.
...
:choice
set /P c=Do you want to rsync the archives to someHost[Y/N]?
if /I "%c%" EQU "Y" goto :syncthefiles
if /I "%c%" EQU "N" goto :doonotsyncthefiles
goto :choice
:syncthefiles
echo rsync files to somewhere ...
bash -c "rsync -vaz /mnt/d/Archive/Backup/ user#host:/home/user/Backup/blabla/"
echo done
:doonotsyncthefiles
echo Backup Complete!
...
You can have as many as you need of these blocks.
You can consider using a UI confirmation.
With yesnopopup.bat
#echo off
for /f "tokens=* delims=" %%# in ('yesnopopup.bat') do (
set "result=%%#"
)
if /i result==no (
echo user rejected the script
exit /b 1
)
echo continue
rem --- other commands --
the user will see the following and depending on the choice the script will continue:
with absolutely the same script you can use also iexpYNbutton.bat which will produce similar popup.
With buttons.bat you can try the following script:
#echo off
for /f "tokens=* delims=" %%# in ('buttons.bat "Yep!" "Nope!" ') do (
set "result=%%#"
)
if /i result==2 (
echo user rejected the script
exit /b 1
)
echo continue
rem --- other commands --
and the user will see:
I would do it in the following way to make sure the testing and variables are correct during looping etc..
:: rem at the top of the script
setlocal enabledelayedexpansion
:: choice example
CHOICE /C YNC /M "Continue? Press Y for Yes, N for No or C for Cancel."
If /I "[!errorlevel!]" NEQ "[1]" ( GOTO START_OVER )
There are so many answers, but none of them seems to be simple and straight forward. This is the code I am using:
choice /M "Do you want to continue?"
if %errorlevel% EQU 1 (
... run your code lines here
)
First, open the terminal.
Then, type
cd ~
touch .sure
chmod 700 .sure
Next, open .sure and paste this inside.
#!/bin/bash --init-file
PS1='> '
alias y='
$1
exit
'
alias n='Taskkill /IM %Terminal% /f'
echo ''
echo 'Are you sure? Answer y or n.'
echo ''
After that, close the file.
~/.sure ; ENTER COMMAND HERE
This will give you a prompt of are you sure before continuing the command.
Open terminal. Type the following
echo>sure.sh
chmod 700 sure.sh
Paste this inside sure.sh
#!\bin\bash
echo -n 'Are you sure? [Y/n] '
read yn
if [ "$yn" = "n" ]; then
exit 1
fi
exit 0
Close sure.sh and type this in terminal.
alias sure='~/sure&&'
Now, if you type sure before typing the command it will give you an are you sure prompt before continuing the command.
Hope this is helpful!