2009-12-30 103 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

相關問題