I'm working on a small batch script, which includes a section similar to the code block below... it would be an understatement to say this has befuddled me to the point where my mind has gone completely numb... why on gaias green backside does this not work...?
#echo off
set log=0
choice /m "Choose "
if errorlevel 2 set log=N
if errorlevel 1 set log=Y
echo %log%
pause
if "%log%"=="N" (
echo hello
)
if "%log%"=="Y" (
echo goodbye
)
pause
if errorlevel 2 set log=N
if errorlevel 1 set log=Y
translated:
if errorlevel is 2 or greater than 2 set log=N
if errorlevel is 1 or greater than 1 set log=Y
so - reverse the lines since if errorlevel is 2, it is both 2 or greater than 2 (so set N) and then is 1 or greater than 1 (so set Y)
An oddity within Windows (and old DOS) is that if you set "if errorlevel ..." it actually means "if the errorlevel is greater than this number..." So if you say "if errorlevel 1" you mean "if errorlevel > 1".
Try this:
if errorlevel 1 if not errorlevel 2 (do stuff)
if errorlevel 2 if not errorlevel 3 (do other stuff)
Alternatively, you can use the temporary variable %ERRORLEVEL%...
Related
Can anyone please help me with understanding the below script from the "typeset" part in the script and what the while and if statements are doing in the script:
# Set effective dates for tasks
set -A EDATE `sqlplus -s / << ENDSQL
set pages 0 feed off
set timing off
alter session set nls_date_format='DD-MM-YYYY';
select sysdate + 42, sysdate + 51, sysdate + 50 from dual;
ENDSQL`
# Check effective dates set
# ${EDATE[0]} = SYSDATE + 42 for tasks NORMALISED
# ${EDATE[1]} = SYSDATE + 51 for tasks SUBTOTAL, SUBTOTAL_RAT
# ${EDATE[2]} = SYSDATE + 50 for tasks NORMALISED_EV,CHARGE
typeset -i C=0
while [[ $C -lt 3 ]] ; do
if [[ -z "${EDATE[C]}" ]] ; then
echo "FAILED TO SET ROTATE PARTITION TASKS EFFECTIVE DATE! PLEASE CHECK."
sms "${SV_SL}" "Failed to set Rotate Partition Tasks effective date. Please check."
exit -1
fi
let C+=1
done
In the first line you've used builtins which is used for permit modifying the properties of variables. You can use 'declare' as well. Both are nearly equal.
In your if statement line you've included semicolon ; which isn't really required at that place. The right if..else syntax in unix is as following given.
Same for while loop also, just remove the semicolon
If..else statement
x=5
y=20
if [ $x == $y ]
then
echo "x is equal to y"
else
echo "x is not equal to y"
fi
Above code's output: x is not equal to y
for while loop
a=0
while [ $u -lt 5 ]
do
echo $u
a=`expr $u + 1`
done
Above code's output:
0
1
2
3
4
-lt 5 indicates limits up to 5 for the while loop.
Also -z option used in if condition that is for variable or string is null.
i.e.
$ip="";
$[-n "$ip"] && echo "ip is not null"
$[-z "$fip"] && echo "ip is null"
Above code's output: ip is null.
iam trying to put if loops in batch script but not getting desired result, please look into code ans suggest where iam wrong in if loop
IF %banned% == 1 echo "vvvvv" it not comparing properly
even 1==1 and 1==0 is same for batch script?
call E:\utility\batfiles\DBAEnvProd.cmd
set dbname=UMRdb
set proc=UMRdb.[dbo].[maintenancemode]
call %osqlExeLocation% -E -d%dbname% -S%svr% -w%w% -b -Q"exec %proc%" -o%pathout%%Maintmode.txt
#echo on
set "usrname=Y"
set "banfile=E:\utility\sysout\Maintmode.txt"
find /i "%usrname%" "%banfile%" >nul 2>&1&&set /a banned=1 || set /a banned=0
echo %banned%
echo comparing maintenance
IF %banned% == 1 echo "vvvvv"
(
here banned is 1 then i dont want to execute rest of code it shd
go to endgood
)
else
normal code should be executed
#echo on
REM ********************************************************************************
REM JOB: TCMP_DBA_M_MNT_UMR_ESSENTIAL
REM
REM ********************************************************************************
set job=TCMP_DBA_M_MNT_UMR_ESSENTIAL
set RetCode=0
time /T & date /T
erase %pathout%%job%*.suc > nul
erase %patherr%%job%*.err > nul
REM ********************************************************************************
REM to display date and time
for /F "tokens=1-3 delims=:. " %%A in ('time/T') do set var=%%A%%B%%C%
set timestamp=%date:~4,2%%date:~7,2%%date:~10,4%
set timestamp1=%timestamp%%var%
REM
REM ********************************************************************************
:main
echo --- DB Growth Info
set proc=UMRdb.[dbo].[spCollectDBSpaceInfo]
call %osqlExeLocation% -E -d%dbname% -S%svr% -w%w% -b -Q"exec %proc%" -o%pathout%%job%_spCollectDBSpaceInfo.txt
if errorlevel 1 (
set RetCode=1
goto endbad
)
echo --- Cleanup of output files older than 30 days in sysout folder
call forfiles -p E:\utility\sysout /D -30 /M *.txt /C "cmd /c del #file"
:ENDGOOD
set RetCode=0
ECHO SUCCESS!!! %svr% %job% %proc%
echo %ErrMsg% > %pathout%%job%.SUC
GOTO END
:ENDBAD
set RetCode=1
ECHO ERROR!!! %svr% %job% %proc%
echo SEE %pathout%%job%_%proc%.txt FOR ERRORS > %patherr%%job%.ERR
:END
time /T & date /T
echo %RetCode%
%pathexe%cc.exe %RetCode%
REM EXIT
this is problematic
IF %banned% == 1 echo "vvvvv"
if == performs a string comparision and i'm seeing lots of spaces. if %banned% is 1 here you are comparing " 1" == "1 ". As you set/a banned=1, it would be better do a numeric comparision
IF %banned% EQU 1
or quoted string comparision
If "%banned%" == "1"
So, I'm making a game using batch coding, and I have a shop within the game that's only supposed to sell one of each item. Unfortunately, when I set the variable for the item to 1, then reduce it to 0, the code doesn't acknowledge that there are no more items to sell.
:ForestHagShop
cls
set WSwrdHag=1
set WShldHag=1
set GldApHag=1
echo "What would you like, my dear?"
echo 1.) Wooden Sword - 50 gold - (+10 Attack)
echo 2.) Wooden Shield - 70 gold - (+30 Max HP)
echo 3.) Shiny Apple - 40 gold - (+30 HP)
echo.
set /p input6=)
if %input6% equ 1 goto BuySwrdHagChk
if %input6% equ 2 goto BuyShldHag
if %input6% equ 3 goto BuyAplHag
:BuySwrdHagChk
echo Checking...
echo.
echo **PRESS A KEY**
Pause >nul
if WSwrdHag LSS 1 goto OutSwordHag
:BuySwrdHag
set /a Gold=Gold-50
set /a Attack=Attack+10
set /a WSwrdHag=WSwrdHag-1
echo You hand over 50 gold for the
echo wooden sword. Your new stats are...
echo Health Points .. .. .. %HP%/%MaxHP%
echo Gold .. .. .. .. .. .. %Gold%
echo Attack Power .. .. .. %Attack%
echo.
echo **PRESS A KEY**
pause >nul
goto ForestHagShop
:OutSwordHag
echo The hag frowns, looking at you like
echo you're stupid.
echo "You already bought my wood sword,
echo idiot!"
echo.
echo **PRESS A KEY**
pause >nul
goto ForestHagShop
Looks like you forgot the % delimiters when checking the variable...
Change
if WSwrdHag LSS 1 goto OutSwordHag
to be
if %WSwrdHag% LSS 1 goto OutSwordHag
and also these
set /a Gold=Gold-50
set /a Attack=Attack+10
set /a WSwrdHag=WSwrdHag-1
to be
set /a Gold=%Gold%-50
set /a Attack=%Attack%+10
set /a WSwrdHag=%WSwrdHag%-1
I am trying to use !errorlevel! as a condition inside a loop. I pass error level in a call and then I try and use findstr again to set errorlevel but the condition is not seeing the change.
setlocal EnableDelayedExpansion
for /F %%i in (%Newzips.lst%) do (
echo unzipping %%i >> test.log
wzunzip -o %%i
call :startloop
)
exit /B
:startloop
dir /b *.dat > %Stagedat.lst%
for /F %%l in (%Stagedat.lst%) do (
dir /b E:\NOMADD_FILES\AV\*.dat > %AVdat.lst%
findstr /i /c %%l %AVdat.lst%
echo top error level - !errorlevel!
call :checkdup %%l !errorlevel!
)
exit /B
:checkdup
if !errorlevel! == 0 (
dir /b E:\NOMADD_FILES\AV\*.dat > %AVdat.lst%
findstr /i %1 %AVdat.lst% >> test.log
echo found match so sleep e >> test.log
echo error level - !errorlevel! >> test.log
sleep 3
echo duplicate in AVdat.lst >> test.log
call :checkdup %1 !errorlevel!
)
if !errorlevel! == 1 (
echo copying file %2 >> test.log
move /Y %1 E:\NOMADD_FILES\AV
sleep 5
dir /b E:\NOMADD_FILES\AV\*.dat > %AVdat.lst%
echo moveing AVdat.lst >> test.log
echo error level - !errorlevel! >> test.log
type %AVdat.lst% >> test.log
)
exit /B
:end
So what is happening is after I get down to :checkdup and findstr runs again, !errorlevel! is being updated to 1 but it is still staying inside the top if statement.
This is a sample from the log.
top error level - 0
bcs3_ammo_inv_updates.dat
found match so sleep e
error level - 0
duplicate in AVdat.lst
bcs3_ammo_inv_updates.dat
found match so sleep e
error level - 0
duplicate in AVdat.lst
bcs3_ammo_inv_updates.dat
found match so sleep e
error level - 0
duplicate in AVdat.lst
found match so sleep e
error level - 1
duplicate in AVdat.lst
found match so sleep e
error level - 1
duplicate in AVdat.lst
found match so sleep e
error level - 1
So error level is being set to 1 but it is stuck in the if !errorlevel! == 0 condition. It should go to the other check and continue through the for loop. I've been stuck on this for a couple days now trying many different combinations to get it to work.
Thanks
:checkdup
if !errorlevel! == 0 (
...
echo error level - !errorlevel! >> test.log
sleep 3
rem AND AFTER SLEEP, which is the value of errorlevel?
call :checkdup %1 !errorlevel!
)
sorry for the question I am a total beginner in programming and probably this is very easy for someone who knows what to do:
I need to create, into a txt file, a serie of links with incremental numbers, for example I want to keep a certain part "fixed" and a part has to change; for example imagine this:
http://user:password#website.com/members/sets/001/somethingfixed-001.zip
in the text the following lines should be:
http://user:password#website.com/members/sets/002/somethingfixed-002.zip
etc..
I think there must be a way to generate those where I could specify, create the link keep the fixed part equal in every line and then incrementally put 001, 002, 003, up to the point i need it.
it could be awesome if I could create a .bat file that would ask me: what is the initial link, what is the part to be fixed and what to change.
I'd do the program like this:
insert the first link, and I paste it.
then it asks me for what is the fixed part and I put:
.../members/sets/X/somethingfixed-Y.zip
what is the range for the variables X and Y?
starting number? and I put 001 and then it asks me what is the end number? and i put 150
and it generates the links in the txt file so that I can use them.
Hope it is clear.
Cheers
Example
This will do it for the first number X, I will leave some of it for you to develop and learn. :)
#echo off
setlocal EnableExtensions EnableDelayedExpansion
echo LeftXRight Gen
set /p "Left=Left = "
set /p "Right=Right = "
set /p "Start=Begin = "
set /p "End=End = "
>output.txt ( <nul set /p "=" )
for /L %%A in (%Start%, 1, %End%) do (
set "X=00%%A"
echo !Left!!X:~-3!!Right!>>output.txt
)
endlocal
Output
LeftXRight Gen
Left = http://user:password#website.com/members/sets/
Right = /somethingfixed.zip
Start = 1
End = 10
output.txt
http://user:password#website.com/members/sets/001/somethingfixed.zip
http://user:password#website.com/members/sets/002/somethingfixed.zip
http://user:password#website.com/members/sets/003/somethingfixed.zip
http://user:password#website.com/members/sets/004/somethingfixed.zip
http://user:password#website.com/members/sets/005/somethingfixed.zip
http://user:password#website.com/members/sets/006/somethingfixed.zip
http://user:password#website.com/members/sets/007/somethingfixed.zip
http://user:password#website.com/members/sets/008/somethingfixed.zip
http://user:password#website.com/members/sets/009/somethingfixed.zip
http://user:password#website.com/members/sets/010/somethingfixed.zip
Update
Added this complete solution to the question.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
echo LeftXMidXRight Gen
set /p "Left=Left = "
set /p "Middle=Middle = "
set /p "Right=Right = "
set /p "Start=Begin = "
set /p "End=End = "
>output.txt ( <nul set /p "=" )
for /L %%A in (%Start%, 1, %End%) do (
set "X=00%%A"
echo !Left!!X:~-3!!Middle!!X:~-3!!Right!>>output.txt
)
endlocal
Example
LeftXMidXRight Gen
Left = http://user:password#website.com/members/sets/
Middle = /somethingfixed-
Right = .zip
Begin = 1
End = 150
output.txt
http://user:password#website.com/members/sets/001/somethingfixed-001.zip
http://user:password#website.com/members/sets/002/somethingfixed-002.zip
...
http://user:password#website.com/members/sets/150/somethingfixed-150.zip
This gets near what you are after, with a couple of limitations..
It can only append to the end of the url.
1 and 2 digit numbers are not zero prefixed.
#echo off
set /p url="Enter URL: "
set /p start="Start Number: "
set /p end="End Number: "
for /L %%X in (%start%, 1, %end% ) do echo %url% %%X >> file.txt