0

Pleskのイベントの1つを介して起動されたバッチファイルを使用して、DNSゾーンの作成を自動化しようとしています。

dnscmdコマンドを使用して、バッチはゾーンが存在するかどうかを確認します。ゾーンが存在しない場合、スクリプトは仕様に従ってゾーンを追加します。それが存在し、それがセカンダリゾーンである場合、スクリプトは仕様に従ってそれを削除して再作成します。存在し、プライマリゾーンである場合、スクリプトはそれをそのままにします。その部分はすべて機能しています。

カスタム構成がいくつかあるので、ゾーンがセカンダリゾーンである場合は、ターゲットサーバーもマスターとして使用していることも確認したいと思います。別のマスターを使用している場合は、そのままにしておきます。マスターサーバーのリストを取得することはできましたが、出力に奇妙な問題があったため、テキストを一致させることができませんでした。Windowsは行末マーカーとして0x0d、0x0aを使用し、バッチ環境はこれを認識します。ただし、この特定の出力行では、行末に追加の0x0dが含まれます。EOLは0x0d、0x0d、0x0aとしてマークされます。

問題のセクションは:check3ラベルの後にあります。FOR / Fループから奇妙なフィードバックを受け取り、デバッグに役立つechoコマンドを追加しました。最終的に、dnscmdの出力を16進エディターに直接ロードして確認しました。以下のスクリプトに示されているアルゴリズムを使用すると、テスト変数%%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=
4

1 に答える 1

0

FOR "call :subroutine" と SET substring 機能を組み合わせて使用​​することで、余分な CR (0x0D) 文字を無視するスクリプトを取得できました。

最初に、DNSCMD から取得した CR CR LF 配置で、数行に余分な CR を含むテスト ファイルを作成しました。複数行の FOR ステートメント (括弧の間の行) の本体の変数がすべて一度に展開されることに気付いたとき、余分な CR を削除する SET サブストリング機能を実際に理解しようとしていたので、SET サブストリング操作は行われません。動作しません。代わりに、これらのコマンドを 1 行ずつ実行する必要があったため、「call :subroutine」機能にたどり着きました。

":show" サブルーチンに渡される行の残りを取得するには、3 番目の変数を引用符で囲む必要がありました。余分な 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 パラメータをサブルーチンに渡すだけで、すべて設定され、引用符の追加と削除について心配する必要がなくなります。DNSCMD について十分な知識がないため、出力を複製できません。それ以外の場合は、より具体的な解決策を提供します。

于 2010-01-07T17:39:39.393 に答える