Batch parameters in IF. syntax error - batch-file

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.

Related

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

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

Removing values from set in Batch

I'm trying to write a script for work that tells me which machines on a network are online and which are offline.
Currently I have it showing me online/offline status, taking the PC names from a text file as input into a set variable.
The code I have so far is:
#echo off
setlocal EnableDelayedExpansion
for /F "tokens=*" %%a in (VC.txt) do call :append %%a
:ping
for %%i in (%VC) do (
ping %%1 -n 1 >nul
call :test %%i
)
echo.
goto :ping
:test
IF %ERRORLEVEL% EQU 0 (
echo Pinging %1
) else (
echo Off %1
)
goto :eof
:append
if defined VC (
set VC=%VC% %1
) else (
set VC=%1
)
What I want to happen is once a machine comes online, to remove it from the list. Basically just only show the list of the offline machines.
Is this possible without wiping the whole set and creating it fresh?
This mod do what you want:
:test
IF %ERRORLEVEL% EQU 0 (
echo Pinging %1
REM Remove this machine from the list
set "VC=!VC: %1=!"
) else (
echo Off %1
)
goto :eof
However, you have a couple small errors in your code. This is the fixed section:
:ping
for %%i in (%VC%) do (
ping %%i -n 1 >nul
call :test %%i
)
echo.
goto :ping
A couple points unrelated to your problem. If the machine names are single words with no spaces, then the "tokens=*" part in the for command is not needed. Also, all those call's and subroutines just complicate the code. This is the way I would do this:
#echo off
setlocal EnableDelayedExpansion
set "VC="
for /F %%a in (VC.txt) do set "VC=!VC! %%a"
:ping
for %%i in (%VC%) do (
ping %%i -n 1 >nul
IF !ERRORLEVEL! EQU 0 (
echo Pinging %%i
REM Remove this machine from the list
set "VC=!VC: %%i=!"
) else (
echo Off %%i
)
)
echo/
if defined VC goto :ping
echo All machines are on line

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.)

About verbose methods in command line for windows and phrasing through things

:: preserve environment variable settings
setlocal
setlocal enabledelayedexpansion
:: check to see if switches are passed
set arg=%1
set verbose=NO
if "%arg:~,1%" == "/" (
if /i "%arg%" == "/v" (
set verbose=YES
echo verbose option is !verbose!
shift /1
) else if "%arg%" == "/?" (
:: display a usage message for a /? switch
echo.
echo Usage: %0 [/?] [servername] ...
echo This batch file displays server
echo statistics for each passed server name.
exit /b 1
)
if "%1" == "" (
set /p servers="Please input the server names: "
) else (
set servers=%*
)
:: process each server name
for %%s in (%servers%) do call :srvDetails %%s
:: restore environment variable settings
endlocal
goto :EOF
:: subroutine to check the server details
:srvDetails
echo.
:: only display is verbose is set
if "%verbose%" == "YES" echo Checking server details for %1
nslookup %1
pause
exit /b
I wrote this code and i am trying to when someone inputs like subtest.bat /v cod.edu meaning that put a /v and a server to check the shift command will then shift it over and not run it through the nslookup while still enabling the verbose to ON. Can anyone help with this?
set servers=%* is your problem. When you do shift, %* remains unchanged, so you need to manually remove the flag:
set "servers=%*"
[...]
if "%1"=="/v" (
[...]
set "servers=!servers:~3!"
)

Resources