我遇到的问题是,一些DNS条目提供别名和附加的IP6地址,而另一些条目确实提供了几个IP4地址,这些地址可能会因答案而异。
仅向DNS服务器请求IP4,确实会导致脚本超时,并且不会解决不断变化(负载平衡)的IP4地址。
为了测试,您可以使用这些域,例如:
- www.stackoverflow
- www.heise.de
- www.dell.de
这些都是很好的例子,因为第一个域确实在IP地址后面提供了一个别名,我可以很容易地通过查找进行筛选。但第二个确实提供了IP6,也应该进行过滤,最后,戴尔几乎为每个返回的答案提供了不同的地址。
这是我的部分代码:
set TESTDNS=www.dell.de
set TESTIP=143.166.83.190
FOR /F "skip=1 delims=: tokens=2 usebackq" %%j in (`nslookup %TESTDNS% 2^>NUL 1^| find "Address"`) do set XIP=%%j
set XIP=%XIP: =%
do more like compare etc. ....
if NOT %TESTIP%==%XIP% ( ... )
有人能告诉我如何过滤IP6地址吗(也许用findstr[0-9]-但更多的是如何检查我最后一个已知的IP地址是否在提供的新答案中,因为如果是这样,我不需要在我的配置中更改它。
解决方案:
根据MC ND的回答,我将他的函数用作直接代码(用于另一个循环),而不使用调用。我真正改变var名称的唯一一件事是从IP中添加条形空白,否则会破坏"1.2.3.4" =! "1.2.3.4 "
D)的功能
for x do ( ...
REM go get dns resolution and set vars to test and compare
set "XIP="
for /f "skip=1 tokens=*" %%a in ('nslookup "%TESTDNS%" 2^>nul ^| findstr /i /r /c:"address[e]*[s]*:.*." /c:"address[ ]*=.*." /c:"^[ ][ ]*[0-9].*." ') do (
rem get nslookup output
set "_line=%%a"
rem remove spaces
set "_line=!_line: =!"
rem parse line
for /f "tokens=1,* delims=:=" %%b in ("!_line!") do (
rem retrieve the correct section of the line
if "%%c"=="" (
set "XTIPX=%%b"
) else (
set "XTIPX=%%c"
)
REM trim whitespaces from var
set XTIPX=!XTIPX: =!
rem test address match to old address
if "!XTIPX!"=="%TESTIP%" (
set "XIP=!XTIPX!"
goto endRESTESTDNS
)
rem if no match, the first address found is saved
if not defined XIP set "XIP=!XTIPX!"
)
)
:endRESTESTDNS
do more like compare etc. ....
实验代码:
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
REM ++++++++++++++++++++++++++++ BLAT EMAIL CONFIG ++++++++++++++++++++++++++++++++++++
set eMailTO=someone@somedomain.somewhere
set eMailFROM=dnstestscript
set server=0.0.0.0
REM you have to install blat of course, here "echo blat ..." is used where it would be
REM useful to send an email on interesting items, but it is also sent to shell and log
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM ++++++++++++++++++++++++++++ SCRIPT CONFIG ++++++++++++++++++++++++++++++++++++++++
set "XScriptnamE=%~n0"
set "XSCRIPTDIR=%~dp0"
set "LOGDIR=%XSCRIPTDIR%%XScriptnamE%"
if not exist "%LOGDIR%" mkdir "%LOGDIR%"
set "LOG=%LOGDIR%%XScriptnamE%.log"
REM make errorlooging expand
set "XLOGX=xpipex && type xpipex && type xpipex >> %LOG%"
REM or make individual run logs
REM set "LOG=%LOGDIR%%XScriptnamE%-%STAMP%.log"
REM not global vars come here
set "DNSTESTFILE=%XSCRIPTDIR%dnstests.txt"
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM do never set something here at errorlog plz otherwise compare of happened errors wont work
set errorlog=
pushd=%XSCRIPTDIR%
REM ++++++++++++++++++++++++++++ MAKE DATE ++++++++++++++++++++++++++++++++++++++++++++
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j
REM make timestamp (date reverse)
set STAMP=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2%--%ldt:~8,2%-%ldt:~10,2%--%ldt:~12,2%-%ldt:~15,3%
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
echo ================================================== >> %LOG%
echo Script run at %STAMP% >> %LOG%
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM ++++++++++++++++++++++++++++ START ++++++++++++++++++++++++++++++++++++++++++++++++
REM if the script is run in cmd we see enoght information to follow actions but they are written to a log file too for sheduled use
REM ++++++++++++ make a loop for each line in file ++++++++++++++++++++++++++++++++++++
REM read them in different vars to call processing
REM check for test file
if NOT exist "%DNSTESTFILE%" (
set errorlog=%errorlog% : error dns file not exist :
echo blat error dnsfile
echo error dnsfile not exist >> %log%
)
REM read test file
set Counter=1
for /f %%s in (%DNSTESTFILE%) do (
set "Line_!Counter!=%%s"
set /a Counter+=1
)
set /a NumLines=Counter - 1
REM make a backup of old test file before nulling it, by files date you see last ip change
copy /y %DNSTESTFILE% %DNSTESTFILE%.bak 2>&1 > %XLOGX%
REM as i found no way to rewrite the specific line i choose to read out all lines in vars, now we nul the file and rewrite lines later
type NUL > %DNSTESTFILE%
REM now use vars to call processing
for /l %%r in (1,1,%NumLines%) do (
set "q=!Line_%%r!"
echo. >> %log%
echo.
call :check !q!
)
REM did all go well or what did we miss?
if NOT "%errorlog%."=="." (
echo.
echo blat summary %errorlog%!
echo. >> %LOG%
echo %errorlog%! >> %LOG%
)
REM ++++++++++++++++++++++++++++ END +++++++++++++++++++++++++++++++++++++++++++++++++++
REM next line tells us script did run through code while one may want to save this lines
echo ==================script finished================= >> %log%
del xpipex
break
goto :eof
REM ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
REM +++++++++++++++++++++++++++++ PROCESSING +++++++++++++++++++++++++++++++++++++++++++
:check
REM trim whitespace from beginning and end of line
for /f "tokens=* delims=" %%z in ("!q!") do (
set "line=!q!"
REM test if line is valid dns AND ip address syntax BUT only informational because of limited regular expression support of findstr and "1234.2.3.4" is also accepted as well formatted address
echo !line! | findstr /i /r "^[a-z0-9-]*.[a-z0-9-]*.[a-z0-9-]*=[0-9]*.[0-9]*.[0-9]*.[0-9]*" >NUL || (
echo blat error in dns test line syntax with: !line!
set errorlog=%errorlog% : error in dns test line syntax with: !line! :
)
REM test that trimmed line matches at least once "^char=number$" and set vars for test
echo !line! | findstr /i "^[a-z]*=[0-9]*$" >NUL && do (
for /f "tokens=1,2 delims==" %%x in ("!q!") do set TESTDNS=%%~x&set TESTIP=%%~y
)
REM trim whitespace from beginning and end of var
set TESTDNS=%TESTDNS: =%
set TESTIP=%TESTIP: =%
echo testing %TESTDNS% to %TESTIP%
echo checking %TESTDNS%: >> %LOG%
REM go get dns resolution and set vars to test and compare
echo. ############################
nslookup %TESTDNS%
echo. ############################
set "XIP="
for /f "skip=1 tokens=*" %%a in ('nslookup "%TESTDNS%" 2^>nul ^| findstr /i /r /c:"address[e]*[s]*:.*." /c:"address[ ]*=.*." /c:"^[ ][ ]*[0-9].*." ') do (
rem get nslookup output
echo testing %TESTDNS% to %TESTIP% -1
set "_line=%%a"
rem remove spaces
set "_line=!_line: =!"
rem parse line
for /f "tokens=1,* delims=:=" %%b in ("!_line!") do (
rem retrieve the correct section of the line
echo testing %TESTDNS% to %TESTIP% -2
if "%%c"=="" (
set "XTIPX=%%b"
) else (
set "XTIPX=%%c"
)
echo testing %TESTDNS% to %TESTIP% -3 "!XTIPX!"
echo !XTIPX! > 1.txt
echo %TESTIP% > 2.txt
REM trim whitespace from beginning and end of var
rem set XTIPX=!XTIPX: =!
rem test address match to old address
if "!XTIPX!"=="%TESTIP%" (
echo testing %TESTDNS% to %TESTIP% -4 !XTIPX!
set "XIP=!XTIPX!"
goto endRESTESTDNS
)
rem if no match, the first address found is saved
if not defined XIP set "XIP=!XTIPX!"
echo testing %TESTDNS% to %TESTIP% -5
)
)
:endRESTESTDNS
REM if dsn did change
if NOT %XIP%==%TESTIP% (
echo %TESTDNS% now is %XIP%
REM inform us
echo blat dns for given %TESTDNS% did change from %TESTIP% TO %XIP%!
echo dns did change from %TESTIP% TO %XIP%! >> %LOG%
REM fill a log-var to report allover later in mail for example
set errorlog=%errorlog% : dns for given %TESTDNS% dis change from %TESTIP% TO %XIP%! :
REM do not forget to write back
echo %TESTDNS%=%XIP% >> %DNSTESTFILE%
)
if %XIP%==%TESTIP% (
REM if dns did not change
echo ip did not change
REM we should not forget to write back the route to our testfile
echo %TESTDNS%=%XIP% >> %DNSTESTFILE%
echo - OK >> %LOG%
)
)
:EOF
@echo off
call :TESTIP "www.dell.de" "1.1.1.1" IP
echo %IP%
exit /B
:TESTIP name oldip retrievedIpVar
setlocal enableextensions enabledelayedexpansion
set "_name=%~1"
set "_oldIP=%~2"
set "_return="
rem Need a variable with a tab in it to use in findstr
call :getTab tab
rem Loop over nslookup filtering output
rem Get lines in the form
rem Address / Addresses : followed by IP
rem blank line start and ip
rem www.somewhere.com internet address = ip
for /f "skip=1 tokens=*" %%a in ('nslookup "%_name%" 2^>nul ^| findstr /i /r /c:"address[e]*[s]*:.*." /c:"address[ ]*=.*." /c:"^[ %tab%][ %tab%]*[0-9].*." ') do (
rem get nslookup output
set "_line=%%a"
rem remove spaces
set "_line=!_line: =!"
rem remove tabs
set "_line=!_line:%tab%=!"
rem parse line
for /f "tokens=1,* delims=:=" %%b in ("!_line!") do (
rem retrieve the correct section of the line
if "%%c"=="" (
set "XIP=%%b"
) else (
set "XIP=%%c"
)
rem test address match to old address
if "!XIP!"=="%_oldIP%" (
set "_return=!XIP!"
goto endTESTIP
)
rem if no match, the first address found is saved
if not defined _return set "_return=!XIP!"
)
)
:endTESTIP
endlocal & set "%~3=%_return%"
goto :EOF
:getTab var
for /f tokens^=^*^ delims^= %%x in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x09"') do ( set "%~1=%%x" )
goto :EOF
跳过第一行(dns服务器信息)。使用冒号和等号作为分隔符。取第二个令牌及其后的所有令牌,因为地址可以包括一个形式为99.99.99.99:999的端口。如果不需要端口,则将令牌更改为token=2
和set "XIP=%%a"
排除IPv6的最简单方法是过滤并只获取其中有一个点的地址字符串
已编辑-已更改以适应平衡地址,其中包括地址前输出中的=
。
编辑2-病例数量比我想象的要多。更改代码以处理更多案例并获得更多IP
编辑3-适用于集成到OP解决方案
编辑4-在nslookup输出中处理行中的初始选项卡
已编辑5-更正选项卡解析的问题