Making a server ping pong tool in batch - loops

I've currently made this but there is a unexpected error in the for loop.
Please help.
#ECHO OFF
COLOR 1F
TITLE (Ash's Script) Server Ping Pong
rem ---------------------------------------------------------------------------------------------------------------
ECHO Started %time% %date% > X:\Scripts\ServerPing.txt
rem ---------------------------------------------------------------------------------------------------------------
FOR /f "tokens=*" %%i in (X:\Scripts\ComputerLists\ServerList.csv) DO (
PING %%i -n 1 -w 3
IF ERRORLEVEL 0 (
ECHO %%i ONLINE %time%>> X:\Scripts\ServerPing.txt
) ELSE (
ECHO %%i OFFLINE %time%>> X:\scripts\ServerPing.txt
)
)
rem ---------------------------------------------------------------------------------------------------------------

IF ERRORLEVEL 0 is always true.
Use this instead:
if not errorlevel 1
Also change the redirection on the echo to files:
>>X:\Scripts\ServerPing.txt ECHO %%i ONLINE %time%
This eliminates a problem when the last character is a number (of a stream)
Another issue is that %time% is evaluated when the loop starts - to get a dynamic time in the log then enable delayed expansion and use !time! instead of %time%

Related

Writing a batch file to detect ping anomalies

I'm trying to create a batch file where it would detect ping anomalies. I want it to ping to an IP infinitely (-t) until I close it where it would write down whenever ms > 100 ms and the time stamp as well. I'm thinking somewhere along the lines of sub string variables but I don't know how to wrap my head around it.
:Loop
time /t >> textfile.txt
ping -n 1 127.0.0.1 | findstr /c:"Minimum" >> textfile.txt
timeout /t 5
Goto Loop
Or perhaps this suits your needs
ping /t > textfile.txt
or
:loop
wmic /append:"textfile.txt" path win32_pingstatus where "address='127.0.0.1' and responsetime > 100" get responsetime,timestamprecord
goto loop
I've been looking for an answer to this same question for while. bgalea's answer gave me the pieces I needed to write my own. Here's what I came up with:
:: usage: badpings.bat [ip adress | hostname] [ping time threshhold]
#echo off
if "%1"=="" (
set pingdest=yahoo.com
) else (
set pingdest=%1
)
if "%2"=="" (
set /a limit=100
) else (
set /a limit=%2
)
echo Pinging %pingdest%.
echo Logging replies over %limit%ms.
echo Press Ctrl+C to end.
:Loop
for /f "usebackq tokens=1-6" %%a in (`ping -n 1 %pingdest% ^| findstr "Request Reply request"`) do (
set var=%%a %%b %%c %%d %%e %%f
set pingtimestr=%%e
)
if "%pingtimestr%"=="find" (
echo Ping request could not find host %pingdest%. Please check the name and try again.
goto End
)
if "%pingtimestr%"=="host" (
set /a pingtime=%limit%+1
)
if "%pingtimestr:~0,4%"=="time" (
set /a pingtime=%pingtimestr:~5,-2%
)
if %pingtime% GTR %limit% (
echo [%time%] %var%>>badpings.log
echo [%time%] %var%)
timeout /t 1 /nobreak >nul
Goto Loop
:End
It works on Windows 10. I haven't tested it on other OS versions.

how to handle sqlplus error in batch file

I am new to batch scripting..
I have test.bat batch file in which I am connecting to the different databases. But if ERROR: ORA-12154 or any connection error occurs it display message on command prompt, I want to display it into the result.txt file. I tried ERRORLEVEL but it always shows same ERRORLEVEL here is my test.bat :-
#ECHO On
setlocal enabledelayedexpansion
for /f "delims== tokens=1,2" %%a in (D:\batch\InstallList.txt) do (
sqlplus %%b #D:\batch\mysql.sql
IF %ERRORLEVEL% EQU 0 ECHO CONNECTION ERROR IN %%a >> D:\batch\\result.txt
)
pause;
but its not working; ERRORLEVEL remains same for all databases.
In InstallList.txt
db1=username/password
db2=username/password
db3=username/password
Try next approach with EnableDelayedExpansion:
setlocal enabledelayedexpansion
for /f "delims== tokens=1,2" %%a in (D:\batch\InstallList.txt) do (
sqlplus %%b #D:\batch\mysql.sql 2>> D:\batch\result.txt
set "xERROR=!ERRORLEVEL!"
echo %%a !xERROR!
if !xERROR! NEQ 0 (
ECHO CONNECTION ERROR !xERROR! IN %%a >> D:\batch\result.txt
) else (
ECHO CONNECTED WITH NO ERROR ^(!xERROR!^) IN %%a >> D:\batch\result.txt
)
)
pause
Explanation:
use !ERRORLEVEL! instead of %ERRORLEVEL% to force expanding ERRORLEVEL variable at execution time rather than at parse time: normally an entire FOR loop is evaluated as a single command even if it spans multiple lines of a batch script;
edit add unconditional echo %%a !xERROR! to see which ERRORLEVEL raised factually;
edit add ELSE and log result in both cases;
use !xERROR! NEQ 0 condition rather than !xERROR! EQU 0 as in general a code of 0 (false) will indicate successful completion;
edit2 sqlplus %%b #D:\batch\mysql.sql 2>> D:\batch\result.txt should append any sqlplus error message(s) into the log file. Here 2 in 2>> is a standard error text output handle.

Why I got the same time in for statement of dos-batch file?

I write a batch file to get the start time of cmd in for statement:
for /L %%i in (1,1,3) do (
echo %%i
echo "traceroute %%i start at %date% %time%" >tr%%i.txt
adb shell "/data/local/traceroute smtp.163.com" 2>&1 >>tr%%i.txt
)
but got the same time in 3 result file:
"traceroute 1 start at 2013/03/27 周三 15:48:47.12"
"traceroute 2 start at 2013/03/27 周三 15:48:47.12"
"traceroute 3 start at 2013/03/27 周三 15:48:47.12"
What's wrong?
A FOR loop is parsed from the FOR to its final closing parenthesis (ie. ALL of the codesegment you posted. At this time, ANY %var% will be replaced by the THEN-CURRENT (ie. PARSE-TIME) value of the variable. THEN the code is executed.
Hence %date% %time% were replaced by their values at the time the command was PARSED.
You can overcome the problem in at least three ways:
1/ with DELAYED EXPANSION, invoked by a SETLOCAL ENABLEDELAYEDEXPANSION instruction, when %var% STILL shows the PARSE-TIME value, but !var! shows the RUN-TIME value
2/ Indirect expansion by CALLing %%var%%
3/ Use a subroutine or external batchfile
Try this code:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%i IN (1 2 3) DO (
ECHO START of run %%i
ECHO using ^!time^! : !time! - PARSE TIME was %time%
CALL ECHO using CALL %%%%TIME%%%% : %%TIME%%
CALL :report
timeout /t 5
ECHO using ^!time^! : !time!
CALL ECHO using CALL %%%%TIME%%%% : %%TIME%%
CALL :report
ECHO END of run %%i
ECHO.
)
GOTO :eof
:report
ECHO :report says TIME is %TIME%
GOTO :eof
You should use delayed expansion !variable!s:
#echo off &setlocal enabledelayedexpansion
for /L %%i in (1,1,3) do (
echo %%i
echo "traceroute %%i start at !date! !time!" >tr%%i.txt
adb shell "/data/local/traceroute smtp.163.com" 2>&1 >>tr%%i.txt
)

How to know the output of a previous command in a batch script

#echo off
setlocal enabledelayedexpansion
>result.txt (
for /f %%a in (srvrname.txt) do (
ping -n 1 %%a > nul && echo %%a up||echo %%a DOWN
))
I was doing a ping test for some servers with the above script. I want to understand how the output of the ping command is passed to echo UP or echo DOWN section..As in unix we have $? to know if the previous command executed successfully like if[$? -eq 0] then; do success else failure done.
How does this happen in a batch script. DO WE HAVE A VARIABLE like $? in batch. Please let me know. Also please suggest if we could make the pingtest script any better.
I think you are looking for %errorlevel%.
This will give you the error code for the last command that executed.
if %errorlevel%==0 echo SUCCESS
if %errorlevel%==1 echo FAIL
Note: There is a whole range of errorcodes that could be set, I just used 1 as an example, check the command documentation to find the errorcode's meaning.
Beware though, if you are using %errorlevel% in your for loop you will need to use delayed expansion.
You already have it added on your script (setlocal enabledelayedexpansion), so you just need to change the %'s to !'s.
#echo off
setlocal enabledelayedexpansion
>result.txt (
for /f %%a in (srvrname.txt) do (
ping -n 1 %%a > nul
if !errorlevel!==0 (
echo Ping replied successfully
) else (
echo There was an error
)
))

Controlling the frame rate of an ASCII animation

I'm creating a simple bat file that plays some ASCII animation stored in 120 .txt files. My script works but it works too fast. I'd like to find a way to slow it dow a bit. I've tried the TIMEOUT 1 command but it only plays 1 picture per second which is too slow. Is there a workable solution without moving from Windows 7 command line?
This is my script so far
#echo off
MODE CON: COLS=91 LINES=41
cls
:3
setlocal enableextensions enabledelayedexpansion
FOR /R %%i in (*.txt) do (type "%%i"
)
goto :3
You could use a FOR /L loop to introduce a delay. Here is a script that introduces an approximate 100 msec delay. A simple test near the top computes how many iterations are required to approximate 100 msec. The number will vary between machines. Adjust the definition of msecDelay as required to get your desired result.
#echo off
setlocal
:: Compute the number of iterations required to get the desired delay
set msecDelay=100
set ticks=100000
set "start=%time%"
for /l %%N in (1 1 %ticks%) do rem
set "stop=%time%"
for /f "tokens=3,4 delims=:.," %%A in ("%start%") do set /a start=1%%A%%B-10000
for /f "tokens=3,4 delims=:.," %%A in ("%stop%") do set /a stop=1%%A%%B-10000
if %start% gtr %stop% set /a stop+=6000
set /a delay=msecDelay*ticks/(stop-start)/10
MODE CON: COLS=91 LINES=41
cls
:3
FOR /R %%i in (*.txt) do (
type "%%i"
for /l %%n in (1 1 %delay%) do rem
)
goto :3
I'm wondering if you will get better results by moving CLS within the loop, just before your TYPE statement.
This is a very simple way to slow between frames
Example:
#echo exiting script
ping localhost -n 2 > nul
cls
#echo exiting script .
ping localhost -n 2 > nul
cls
#echo exiting script ..
ping localhost -n 2 > nul
cls
#echo exiting script ...
ping localhost -n 2 > nul
cls
#echo exiting script ....
ping localhost -n 2 > nul
cls
#echo exiting script .....
ping localhost -n 5 > nul
cls
Not built in, but still command line: sleep.exe from Windows Resource Kit (available here: http://www.microsoft.com/en-us/download/details.aspx?id=17657)
Usage: sleep time-to-sleep-in-seconds
sleep [-m] time-to-sleep-in-milliseconds
sleep [-c] commited-memory ratio (1%-100%)

Resources