Prompt is asking question 2 times. How can I fix this? - batch-file

I tried to make a check to see if the EULA is set to true in eula.txt but when typing true it asks again and I have to type true again.
I tried on Windows 10 and using a .cmd file instead of .bat (the same thing)
#echo off
SET jarFileName=server.jar
SET jarFileUrl=https://cdn.getbukkit.org/spigot/spigot-1.12.2.jar
SET memory=4G
SET startColor=0F
SET errorColor=CF
rem Colors and things
color %startColor%
MODE CON COLS=136 LINES=36
rem Start server
:checkEULA1
if exist eula.txt (
goto checkEULA2
) else (
echo eula=false>eula.txt
goto checkEULA2
)
:checkEULA2
>nul findstr /c:"eula=true" eula.txt && (
rem EULA true
goto start
) || (
rem EULA not true
echo Do you accept the EULA? Type true if you do.
set /p eula=
echo eula=%eula% >eula.txt
goto checkEULA1
)
:start
pause
if exist %jarFileName% (
java -version >nul 2>&1|| cls&&color %errorColor%&&echo Please install Java and add it to PATH. Usually the 64 bit JDK works better. && goto exit
cls
java -Xmx%memory% -jar %jarFileName% nogui
) else (
cls
echo %jarFileName% not detected. Downloading...
powershell -Command "(New-Object Net.WebClient).DownloadFile('%jarFileurl%', '%jarFileName%')"
echo Done!
echo.
echo Press any key to start server... && pause>nul && cls && goto start
)
rem Exit
:exit
echo.
color %errorColor%
echo.
echo Press any key to exit... && pause>nul && exit
I want it to only ask the question once. No errors I can see.

I think that you could probably do this a little bit simpler:
#Echo Off
Set "startColor=0F"
Set "errorColor=CF"
Set "jarFileName=server.jar"
Set "jarFileUrl=https://cdn.getbukkit.org/spigot/spigot-1.12.2.jar"
Set "memory=4G"
FindStr /I "^eula=true$" "eula.txt" >NUL 2>&1||(Color %errorColor%
Choice /M "Do you accept the EULA"
If ErrorLevel 2 Exit /B 1
(Echo eula=true)>eula.txt)
ClS
Mode 136,36
Color %startColor%
Rem Start server

The problem is that your eula variable is only set after exiting the findstr function.
An easy solution is to create another function and goto it:
:checkEULA1
if exist eula.txt (
goto checkEULA2
) else (
echo eula=false>eula.txt
goto checkEULA2
)
:checkEULA2
findstr /c:"eula=true" "eula.txt" >nul 2>&1 && (
rem EULA true
goto start
) || (
rem EULA not true
set /p eula= Do you accept the EULA? Type true if you do:
goto setEULA
)
:setEULA
echo eula=%eula%>eula.txt
goto checkEULA1

Related

script not running second function after taking user input

My goal is to first prompt, echo the line, issue the next prompt, then display press any key to exit....
I'm not sure why my batch-file isn't issuing the second prompt.
#echo off
::deploying to test
set /p tdeploy="Deploy to test: [y/n]"
IF /I "%tdeploy%"=="y"(
call :deploy_test
if /I "%ERRORLEVEL%" NEQ "0"(
echo Deploy test failed
)
)
::deploying to argos
set /p adeploy="Deploy to argos: [y/n]"
IF /I "%adeploy%"=="y"(
call :deploy_argos
if /I "%ERRORLEVEL%" NEQ "0"(
echo Deploy argos failed
)
)
set /p DUMMY=Press any key to exit...
:deploy_test
ECHO deploying test!
goto :eof
:deploy_argos
ECHO deploying argos!
goto :eof
:eof
set /p DUMMY=Press any key to exit.222..
I usually prefer to structure it as a nested IF ELSE to avoid a bunch of GOTO commands and having to figure out error levels:
#echo off
REM deploying to test
set /p tdeploy="Deploy to test: [y/n]"
if /i "%tdeploy%" == "y" (
echo deploying test!
) else (
if /i "%tdeploy%" == "n" (
echo deploy test cancelled
) else (
echo seriously, there were only two options...
)
)
)
REM deploying to argos
set /p adeploy="Deploy to test: [y/n]"
if /i "%adeploy%" == "y" (
echo deploying test!
) else (
if /i "%adeploy%" == "n" (
echo deploy test cancelled
) else (
echo seriously, there were only two options...
)
)
)
pause
The pause will be your "Press any key to continue..." - the rest of the spacing is just to make it more visible.
I would suggest you use choice.exe for your Y,N questions:
#Echo Off
Rem Deploying to test
Choice /M "Deploy to test"
If "%ERRORLEVEL%"=="1" (Call :deploy_test
If ErrorLevel 1 Echo Deploy test failed)
Rem Deploying to argos
Choice /M "Deploy to argos"
If "%ERRORLEVEL%"=="1" (Call :deploy_argos
If ErrorLevel 1 Echo Deploy test failed)
Echo Press any key to exit...
Timeout /T -1 >NUL
GoTo :EOF
:deploy_test
Echo Deploying test!
Timeout /T 3 /NoBreak >NUL
Exit /B 0
:deploy_argos
Echo Deploying argos!
Timeout /T 3 /NoBreak >NUL
Exit /B 1
In the example above, I have used two different exit codes, to simulate the returned error level for each of the two deployment options.

Update Currently Running Batch Script

Playing around with my Batch script again. It was brought to my attention that my update routine was not working correctly. Iteration 1 would result in the running script being deleted and not copying the new version from a folder I had selected. Iteration 2 now deletes the old script and copies the new script but with each line of code I change I end up with the currently running script closing, and the new updated script not launching.
Here's a snippet of the Update routine:
:Options
REM I'll set the variable here to what is set elsewhere in the script.
SET VERSION=Version 1.7
CLS
ECHO.
ECHO.
ECHO %VERSION%
ECHO.
ECHO.
ECHO ==================== OPTIONS =====================
ECHO.
ECHO 1. Update Script WIP
ECHO 2. Install entire script to Statup Folder
ECHO 3. Install individual items for auto-launch
ECHO 4. Install Windows Logout feature
ECHO 5. Uninstall
ECHO 6. Change Colors
ECHO 7. Changelog
ECHO.
ECHO =======PRESS 'Q' TO QUIT OR 'B' TO GO BACK========
ECHO.
SET OPTION=
SET /P OPTION=Select an Option:
IF /I '%OPTION%'=='1' GOTO Update
IF /I '%OPTION%'=='2' GOTO Install
IF /I '%OPTION%'=='3' GOTO I_Install
IF /I '%OPTION%'=='4' GOTO I_Logout
IF /I '%OPTION%'=='5' GOTO Uinstall
IF /I '%OPTION%'=='6' GOTO Colors
IF /I '%OPTION%'=='7' GOTO Changelog
IF /I '%OPTION%'=='q' GOTO quit
IF /I '%OPTION%'=='quit' GOTO quit
IF /I '%OPTION%'=='b' GOTO menu
IF /I '%OPTION%'=='back' GOTO menu
ECHO.
ECHO ============INVALID INPUT============
ECHO Please select a number
ECHO or select 'Q' or 'B'.
ECHO ======PRESS ANY KEY TO CONTINUE======
PAUSE > NUL
GOTO Options
:Update
ECHO.
IF EXIST "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\Shortcut Browser *.bat" (
GOTO Update_1
) ELSE (
ECHO You have not installed the script yet. Please install the script first.
)
PAUSE
GOTO Options
:Update_1
IF EXIST "%userprofile%\AppData\Local\Temp\Update.bat" (
GOTO Update_2
) ELSE (
REM Here the main script writes an update script to a batch file
ECHO DEL "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\Shortcut Browser *.bat" > "%userprofile%\AppData\Local\Temp\Update.bat"
REM I replaced the original file location with one on the desktop. The original location was on a network drive, location is confidential.
ECHO COPY "%userprofile\Desktop\Shortcut Browser *.bat" "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup" >> "%userprofile%\AppData\Local\Temp\Update.bat"
ECHO CALL "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\Shortcut Browser *.bat" >> "%userprofile%\AppData\Local\Temp\Update.bat"
ECHO EXIT >> "%userprofile%\AppData\Local\Temp\Update.bat"
)
GOTO Update_2
REM Here the main script calls upon the update script
:Update_2
CALL "%userprofile%\AppData\Local\Temp\Update.bat"
REM The script seems to hang here. Either both the scripts will remain open or close or a combination depending on where CALL and START were used.
PAUSE
GOTO Options
I saw elsewhere I could have used the FC command. I didn't know about it until troubleshooting this problem. I've gotten this far and I feel I'm just missing some small trick to get the new updated script to launch.
If you need any more info let me know. I think I covered everything.
#ECHO OFF
SETLOCAL
TITLE Super Script 5000
:Options
REM I'll set the variable here to what is set elsewhere in the script.
SET VERSION=Version 1.7
CLS
ECHO.
ECHO.
ECHO %VERSION%
ECHO.
ECHO.
ECHO ==================== OPTIONS =====================
ECHO.
ECHO 1. Update Script WIP
ECHO 2. Install entire script to Statup Folder
ECHO 3. Install individual items for auto-launch
ECHO 4. Install Windows Logout feature
ECHO 5. Uninstall
ECHO 6. Change Colors
ECHO 7. Changelog
ECHO.
ECHO =======PRESS 'Q' TO QUIT OR 'B' TO GO BACK========
ECHO.
SET "OPTION="
SET /P "OPTION=Select an Option: "
IF /I "%OPTION%"=="1" GOTO Update
IF /I "%OPTION%"=="2" GOTO Install
IF /I "%OPTION%"=="3" GOTO I_Install
IF /I "%OPTION%"=="4" GOTO I_Logout
IF /I "%OPTION%"=="5" GOTO Uinstall
IF /I "%OPTION%"=="6" GOTO Colors
IF /I "%OPTION%"=="7" GOTO Changelog
IF /I "%OPTION%"=="q" GOTO quit
IF /I "%OPTION%"=="quit" GOTO quit
IF /I "%OPTION%"=="b" GOTO menu
IF /I "%OPTION%"=="back" GOTO menu
ECHO.
ECHO ============INVALID INPUT============
ECHO Please select a number
ECHO or select 'Q' or 'B'.
ECHO ======PRESS ANY KEY TO CONTINUE======
PAUSE > NUL
GOTO Options
:Update
ECHO.
IF EXIST "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\Shortcut Browser *.bat" (
GOTO Update_1
) ELSE (
ECHO You have not installed the script yet. Please install the script first.
)
PAUSE
GOTO Options
:Update_1
IF EXIST "%tmp%\update.bat" (
2>NUL DEL "%tmp%\update.bat" || GOTO Options
)
SETLOCAL
FOR %%A IN (
"%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\Shortcut Browser *.bat"
) DO (
SET "old_version=%%~A"
SET "old_dir=%%~dpA"
SET "old_file=%%~nxA"
)
FOR %%A IN (
"%userprofile%\Desktop\Shortcut Browser *.bat"
) DO (
SET "new_version=%%~A"
SET "new_dir=%%~dpA"
SET "new_file=%%~nxA"
)
IF NOT DEFINED old_version (
ENDLOCAL
GOTO Options
) ELSE IF NOT DEFINED new_version (
ENDLOCAL
GOTO Options
)
(
ECHO #ECHO OFF
ECHO SETLOCAL
ECHO.
ECHO ECHO Update and restarting...
ECHO ^>NUL PING localhost -n 3
ECHO.
ECHO SET "old_version=%old_version%"
ECHO SET "new_version=%new_version%"
ECHO SET "updated_version=%old_dir%\%new_file%"
ECHO.
ECHO CALL :log /clear_log
ECHO.
ECHO IF NOT EXIST "%%new_version%%" (
ECHO CALL :log ERROR: Not exist "%%new_version%%".
ECHO EXIT /B 1
ECHO ^)
ECHO.
ECHO CALL :log Move old_version to old_version.bak.
ECHO MOVE "%%old_version%%" "%%old_version%%.bak" ^|^| (
ECHO CALL :log ERROR: Move failed to backup old version.
ECHO EXIT /B 2
ECHO ^)
ECHO.
ECHO CALL :log Copy new_version to old_version.
ECHO COPY "%%new_version%%" "%%appdata%%\Microsoft\Windows\Start Menu\Programs\Startup\" ^|^| (
ECHO CALL :log ERROR: Copy failed. Restore old version.
ECHO MOVE "%%old_version%%.bak" "%%old_version%%" ^|^| (
ECHO CALL :log ERROR: Restore old version failed.
ECHO EXIT /B 3
ECHO ^)
ECHO EXIT /B 4
ECHO ^)
ECHO.
ECHO CALL :log Delete old_version.bak.
ECHO DEL "%%old_version%%.bak" ^|^| (
ECHO CALL :log WARNING: Delete backup file failed.
ECHO ^)
ECHO.
ECHO IF NOT EXIST "%%updated_version%%" (
ECHO CALL :log ERROR: Not exist: "%%updated_version%%"
ECHO EXIT /B 5
ECHO ^)
ECHO.
ECHO ENDLOCAL
ECHO.
ECHO ECHO Ready to restart updated version
ECHO PAUSE
ECHO CALL "%old_dir%\%new_file%"
ECHO EXIT /B
ECHO.
ECHO :log
ECHO SETLOCAL
ECHO SET "log=%%tmp%%\update.log"
ECHO IF /I "%%~1"=="/clear_log" TYPE NUL ^> "%%log%%" ^& EXIT /B
ECHO IF /I "%%~1"=="/delete_log" 2^>NUL DEL "%%log%%" ^& EXIT /B
ECHO SET args=%%*
ECHO IF NOT DEFINED args EXIT /B
ECHO ECHO %%*
ECHO ^>^> "%%log%%" ECHO %%*
ECHO EXIT /B
) > "%tmp%\update.bat"
ENDLOCAL
START "Super Script 5000" "cmd /c "%tmp%\update.bat""
EXIT
:Quit
Tested on a Win7 VM. The script needs to restart on update else
weird issues may occur. CMD does not like scripts changing as it
is reading and interpreting them. Even reusing the same console
using START with /B may cause key input issues.
update.bat is overwritten every update as it stores absolute paths
so each update will be different paths with the filenames changing.
Using a wildcard with CALL may not work too well otherwise.
update.bat moves the old version to a .bak file, copies the new
version and if successful, deletes the .bak file, else moves the
.bak file to the old version. This is just to ensure a current
version always exists even if the update fails.
Changed quotes in :Options label from ' to ". Quotes are not
interchangeable like some other languages. Example: "%OPTION%"
will work if contains a space though '%OPTION%' may cause error.
I notice no SETLOCAL at the top of your full script. Advise you add
it unless you have a good reason not to.
I merged labels :Update_1 and :Update_2 into one.
Perhaps adjust Ping localhost -n number if more or less time is
needed.
Look at the %tmp%\update.log if a problem happens. Though expect
the errors to show in the console as the label :log in
update.bat echoes to console and writes to the log.

Batch parameters in IF. syntax error

this is the start of a code I want to use as a cronjob. Based on the Parameter you enter you start the script in different modes.
The Problem is, if I enter a wrong or no parameter I get a Syntax error instead of the Usage echo.
"-v" cannot be processed syntactically at this Point.
#ECHO OFF
SETLOCAL EnableDelayedExpansion
set v=False
set q=False
if %1 EQU -v (
set v=True
) else (
if %1 EQU -q (
set q=True
) else (
ECHO %DATE:~-4%%DATE:~-7,2%%DATE:~-10,2%_%Time% WARN False Parameter %1 >> C:\Users\Jeff\Desktop\%DATE:~-4%%DATE:~-7,2%%DATE:~-10,2%_Log_2.34.log
REM Usage
echo Usage [-v] for verbose mode
echo [-q] for quiet mode
echo.
pause
goto EOF
)
)
Ok, I found the answer.
#ECHO OFF
SETLOCAL EnableDelayedExpansion
set v=False
set q=False
if /i "%~1" EQU "-v" (
set v=True
) else (
if /i "%~1" EQU "-q" (
set q=True
) else (
ECHO %DATE:~-4%%DATE:~-7,2%%DATE:~-10,2%_%Time% WARN False Parameter %1 >> C:\Users\Jeff\Desktop\%DATE:~-4%%DATE:~-7,2%%DATE:~-10,2%_Log_2.34.log
REM Usage
echo Usage [-v] for verbose mode
echo [-q] for quiet mode
echo.
pause
goto EOF
)
)
/i will accept two words in %1 and will not fail if %1 is empty.

Batch errorlevel is not working properly

so i have really problems with the ERRORLEVEL of batch. Its just not working for me.
I have a big own ms build batch script and i always get 0 back from ERRORLEVEL, whatever I do (eg. msbuild, tf get, tf checkout, copy, xcopy,...)
so i did a small example to post it here:
#echo off
set Update=1
IF %Update% == 1 (
echo.
set /p "=- Copy stuff..." <NUL
xcopy /R /Y C:\test\2.lib C:\test1
if %ERRORLEVEL% neq 0 (echo FAILED!) ELSE (echo SUCCEED!)
echo -^> done
pause
)
so its always returning succeed and printing 0 when i do: echo %ERRORLEVEL%
can you please help me with that? I really would like to use that errorlevel
you need delayed expansion here or to use IF ERRORLEVEL :
#echo off
set Update=1
IF %Update% == 1 (
echo.
set /p "=- Copy stuff..." <NUL
xcopy /R /Y C:\test\2.lib C:\test1
IF ERRORLEVEL 1 (echo FAILED!) ELSE (echo SUCCEED!)
echo -^> done
pause
)
with IF ERRORLEVEL 1 you can check if the errorlevel is 1 or bigger .
As npocmaka says, you have a delayed expansion issue.
An alternative is to ditch ERRORLEVEL and use the && and || conditional command concatenation operators instead.
#echo off
set Update=1
IF %Update% == 1 (
echo.
set /p "=- Copy stuff..." <NUL
xcopy /R /Y C:\test\2.lib C:\test1 && (echo SUCCEED!) || (echo FAILED!)
echo -^> done
pause
)
Edit showing use of multiple lines
#echo off
set Update=1
IF %Update% == 1 (
echo.
set /p "=- Copy stuff..." <NUL
xcopy /R /Y C:\test\2.lib C:\test1 && (
echo First success command
echo SUCCEED!
) || (
echo First failure command
echo FAILED!
)
echo -^> done
pause
)

How to find a certain word in a file without using ERRORLEVEL (batch)

I can use ERRORLEVEL, but tried and with a loop it failed.
I am writing a batch "shell."
Since I have tried and tried, I am finally asking for help.
The reason I don't want to use errorlevel is because the loop.
(FULL) SHELL
#set /p build=<"C:\Users\%username%\Desktop\WellOS2\WellOS\Build".txt
#title WellOS V.%build%
#echo off
goto boot
:register
cls
echo You are registering...
echo If this is an error press CTRL + C NOW...
pause
cls
set /p user= Enter your username:
set /p passwordreg= Enter your password:
mkdir "C:\Users\%username%\Desktop\WellOS2\Users\%user%"
mkdir "C:\Users\%username%\Desktop\WellOS2\Users\%user%\Documents"
echo %passwordreg% >"C:\Users\%username%\Desktop\WellOS2\Users\%user%\password".txt
echo 2 >"C:\Users\%username%\Desktop\WellOS2\OSfiles\bootset".txt
echo Your done.
pause
goto welloslog
:booterror
echo Sorry the boot file has an error. Check the user manual for BOOT$
pause
:boot
set /p boot=<"C:\Users\%username%\Desktop\WellOS2\OSfiles\bootset".txt
if %boot% == 1 goto register
if %boot% == 2 goto welloslog
goto booterror
cls
:ERROR
cls
echo ----------ERROR-------------------
echo %error%
pause
goto %back%
:welloslog
cls
echo Welcome to WellOS2!
echo ----------------LOGIN-------------
set /p user= Username:
if exist "C:\Users\%username%\Desktop\WellOS2\Users\%user%" goto pass
set error= Sorry that account doesn't exist.
set back=welloslog
goto welloslogerror
:pass
set /p password=<"C:\Users\%username%\Desktop\WellOS2\Users\%user%\password".txt
set /p passwordlog= Password:
if /i %passwordlog% == %password% goto wellos
set error= Sorry! wrong password.
set back= welloslog
goto error
:wellos
cls
:wellosnocls
echo --------------MAIN---------------
echo type help for help
set /p command= #:
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.sys" set type=sys
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.pro" set type=pro
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.sys" goto po
if exist "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.pro" goto po
set error= !Unreconized program/system program!
set back=wellos
goto error
:po
set lines=0
echo --------------%command%.%type%---------------
:porep
set /a lines=%lines% + 1
set /p "code="<"C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%".wellcode
if "%code%"=="GOWELL" goto wellosnocls
findstr /I /L "if" "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%.wellcode"
:skip
call %code%
goto porep
::Tools
:iftl
%code%
goto porep
PROGRAM OPENER (What I am talking about, and having problems with...)
:po
set lines=0
echo --------------%command%.%type%---------------
:porep
set /a lines=%lines% + 1
set /p "code="<"C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%".wellcode
if "%code%"=="GOWELL" goto wellosnocls
findstr /I /L "if" "C:\Users\%username%\Desktop\WellOS2\Programdata\%command%.%type%\%command%.%type%-%lines%.wellcode" goto iftl
:skip
call %code%
goto porep
::Tools
:iftl
%code%
goto porep
findstr "targetstring" datafilename >flagfilename
for %%a in (flagfilename) do if %%~za==0 echo not found
for %%a in (flagfilename) do if %%~za neq 0 echo found
beyond that, your question is too vague.
The following command returns all lines of a text file textfile.txt that contain the word word (remove the /I switch if you want the search to be case-sensitive):
findstr /I /L "word" "textfile.txt"
With for /F you can capture the output and test whether it is empty, as the loop does not iterate if no match is encountered:
set "FOUND="
for /F "delims=" %%F in ('
findstr /I /L "word" "textfile.txt"
') do (
set "FOUND=Yes"
)
if defined FOUND (
echo One or more matches found.
rem do something...
) else (
echo No match found.
rem do something else...
)
Type for /? and if /? in command prompt to get details about the used commands.
There is also a way to use ErrorLevel implicitly, meaning you do not have to query its value by something like %ErrorLevel%, !ErrorLevel! or if ErrorLevel, namely when using conditional command separators:
the && separator executes the following command only in case the previous one succeeded, that is, it returned an ErrorLevel of 0; (findstr returns 0 in case a match is encountered;)
the || separator executes the following command only in case the previous one failed, that is, it returned an ErrorLevel other than 0; (findstr returns a non-zero ErrorLevel in case no match is encountered;)
The following line of code demonstrates the usage:
findstr /I /L "word" "textfile.txt" && (echo One or more matches found.) || echo (No match found.)

Resources