2009-12-30 102 views
0

我试图通过使用通过Plesk事件激发的批处理文件来自动创建DNS区域。在批处理文件中抓取子字符串

使用dnscmd命令,批处理将检查区域是否存在。如果区域不存在,则脚本根据规格添加它。如果它确实存在,并且它是辅助区域,则该脚本会根据规格删除并重新创建它。如果它存在,并且它是一个主要区域,则该脚本将使其独立。这部分全部正在工作。

由于我们有一些自定义配置,我还想验证如果区域是辅助区域,它也使用目标服务器作为主控。如果它正在使用不同的主人,请保持独立。虽然我能够检索主服务器列表,但由于输出存在奇怪的问题,我无法匹配文本。 Windows使用0x0d,0x0a作为行尾标记,批处理环境可以识别这一点。然而,在这个特定的输出行上,行尾包含一个额外的0x0d; EOL被标记为0x0d,0x0d,0x0a。

问题部分位于:check3标签后面。我收到来自FOR/F循环的一些奇怪反馈,并添加了echo命令以帮助调试。我最终将dnscmd的输出直接加载到十六进制编辑器中查看。使用下面的脚本中显示的算法,我的测试变量%% A和%% B保留了额外的0x0d,从而搞乱了我的比较。我从dnscmd检查的其他行不显示此问题 - 它仅与输出与MasterServers信息相关。我该如何解决这个问题?

要求:批量功能只有 ...我们知道我们可以将其重新编码为VBScript并立即解决问题,但这不是我们的目标。该解决方案不得涉及任何其他应用程序来解析dnscmd的输出。

@echo off 
rem 1.2.3.4 = target server holding Plesk domains 
rem 5.6.7.8 = our public nameservers 

rem *** USER CONFIGURED VARIABLES 
set dnsupdlog=test.log 
set dnsupdip=1.2.3.4 

rem *** other script variables (DO NOT MODIFY) 
rem the next line is "set tab=<tab>%" 
set tab=  % 
set nozone=%1 

rem *** make sure a domain was provided 
if "%1"=="" set nozone=**NO ZONE PROVIDED** 
for /F "delims=" %%A IN ('date /T') DO SET dnsupdtime=%%A 
echo --------%dnsupdtime% begin zone %nozone% > %dnsupdlog% 
if "%nozone%"=="**NO ZONE PROVIDED**" (
    echo You must provide a domain name, e.g., test.bat mydomain.com >> %dnsupdlog% 
    goto :endit 
) 

rem *** does domain exist yet? if not, just add the domain 
"%plesk_bin%\dnscmd.exe" 5.6.7.8 /zoneinfo %1 | find "query failed" > NUL 
if ERRORLEVEL 1 (
    echo Zone exists ... continue checking >> %dnsupdlog% 
    goto :check2 
) 
echo Zone does not exist ... add domains >> %dnsupdlog% 
goto :add_domains 

:check2 
rem *** domain already exists. Is it primary? if yes, skip 
for /F "tokens=1-2 skip=1 delims=%tab%: " %%A IN ('"%plesk_bin%\dnscmd.exe" 5.6.7.8 /zoneinfo %1 Type') DO (
    if "%%A"=="Dword" (if "%%B"=="1" (
    echo Domain is a primary zone. No work to be done. >> %dnsupdlog% 
    goto :endit 
    ) 
    echo Not a primary zone ... continue checking >> %dnsupdlog% 
    goto :check3 
) 
) 
echo ***ERROR*** Could not determine zone type!! >> %dnsupdlog% 
goto :endit 

:check3 
rem *** secondary domain exists. Is it using this as master? if not, skip 
set isfound=no 
for /F "skip=1 tokens=2-3 delims=%tab%=> " %%A IN ('"%plesk_bin%\dnscmd.exe" 5.6.7.8 /zoneinfo %1 MasterServers') DO (
    echo %%A 
    echo %%B 
    echo %%A, 
    echo %%B, 
    if /i "%%A"=="count" (if /i "%%B" NEQ "1" (
    echo Received unexpected master server count %%B!! >> %dnsupdlog% 
    goto :endit 
    ) 
) 
    if /i "%%A"=="Addr[0]" (
    if /i "%%B" NEQ "%dnsupdip%" (
     echo Different master server %%B. No work to be done. >> %dnsupdlog% 
     goto :endit 
    ) 
    set isfound=yes 
) 
) 
if /i "%isfound%" NEQ "yes" (
    echo Did not find expected IP %dnsupdip% as master server. No work to be done. >> %dnsupdlog% 
    goto :endit 
) 

:del_domains 
rem *** delete domains here 
echo del >> %dnsupdlog% 

:add_domains 
rem *** add domains here 
echo add >> %dnsupdlog% 

:endit 
echo --------%dnsupdtime% end zone %nozone% >> %dnsupdlog% 
set isfound= 
set nozone= 
set dnsupdtime= 
set dnsupdlog= 
set dnsupdip= 
+0

如果你被允许使用外部工具,我会通过一些搜索和替换过滤器(例如FART)来管理dnscmd输出,以摆脱那些奇怪的\ r \ r \ n – 2009-12-30 12:17:44

+0

oops,你说你可以“T。然后你卡住了。只有内置命令才能处理特殊字符。 – 2009-12-30 12:23:49

回答

0

我能得到一个脚本中使用的组合FOR忽略额外的CR(0X0D)字符“称:子程序”,并设置子功能。

首先,我在几条线上创建了一个测试文件,其中包含您从DNSCMD获取的CR CR LF布局。实际上我只是试图找出SET子字符串去除额外的CR的能力,当我意识到多行FOR语句(括号之间的行)的变量都立即被扩展时,所以SET子字符串操作不会'工作。相反,这些命令需要一行一行地执行,这导致了我的“调用:子程序”功能。

为了得到传递给“:show”子程序的行的其余部分,我不得不将第三个变量放在引号中,这看起来似乎剥离了具有它的行上的额外CR,整齐地避免了进一步的条件逻辑跳过没有额外的CR线。然后我用子程序中的串操纵删除引号。

@echo off 
for /F "tokens=1,2* delims= " %%A in (testfile.txt) do (call :show %%A %%B "%%C") 
goto :eof 

:show 
    echo A=[%1] 
    echo B=[%2] 
    echo C=[%3] 
    set l=%3 
    : the param needs to be copied to another var for expansion to work 
    set t=%l:~1,-1% 
    echo T=[%t%] 

    echo --- 
    goto :eof 

批处理编程肯定来自于老的DOS天很长的路要走,但即便如此,它只是似乎是一堆解决方法来处理其他变通的副作用!

无论如何,你应该能够倾斜这样的东西让你的脚本工作。在你的情况下,如果你只是将你的%% A和%% B params传递给一个子程序,你可能会全部设置,而不必担心添加和删除引号。我对DNSCMD不够了解,所以我无法复制您的输出,否则我会提供更具体的解决方案。

+0

基本上与其他人在另一个网站上向我提供的相同。他们的例子只是删除了字符串的最后一个字符,而不是先添加其他字符。另外,它们使用“setlocal enabledelayedexpansion”来允许扩展循环内的变量。他们的工作片段: set A = %% A set B = %% B set A =!A:〜0,-1! set B =!B:〜0,-1! – SBink 2010-01-11 14:03:03

相关问题