2016-10-12 10 views
0

私は単純なバッチスクリプトを書いて、たくさんのIPをpingしてオンラインであるかどうかを確認しています。 、私は(エラーメッセージの理由は何ですか?(現時点では予期しなかったものですか?)

を言って、エラーを取得し、この時点で予想外だった。

私は私が間違っていた場所がわからないんだ。誰かがちょうど素晴らしいことだその代わりに何をすべきか私に言うことができるのであれば私のコードは最高ではありませんので、私は一種の新しいバッチです。

::@echo off 
color b 
title Get Online IPs 
for /L %%A IN (0,1,255) do (
    for /L %%B IN (0,1,255) do (
     for /L %%C IN (0,1,255) do (
      for /L %%D IN (0,1,255) do (
       set %%A.%%B.%%C.%%D = IP 
       ping -n 1 %%A.%%B.%%C.%%D > ./iptemp.txt 
       for /F "delims=" %%i in (iptemp.txt) do set "iptemp=%%i" 
       if %iptemp% == "Packets: Sent = 1, Received = 0, Lost = 1 (100% loss)," (
        echo IP offline 
        goto skip 
       ) 
       echo %IP% >> IPlist.txt 
       echo %IP% is online! 
       :skip 
      ) 
     ) 
    ) 
) 

答えて

0

私はIPv4アドレス範囲全体にpingを実行する理由、つまり世界のすべてのIPv4アドレスをpingする理由を理解できません。 4 294 967 296のアドレスをpingしようとしていますか?

set %%A.%%B.%%C.%%D = IPは完全に間違っています。変数の名前と変数に割り当てる文字列の値は、等号の間違った側にあります。また、等号の周りにスペースがない理由については、Why is no string output with 'echo %var%' after using 'set var = text' on command line?をご覧ください。

(で始まり一致する)で終わるコマンドブロック内で変数が定義または変更され、同じコマンドブロック内で変数の値が参照されると、遅延環境変数拡張が必要です。コマンドプロンプトウィンドウset /?で実行し、以下のコードで使用されている遅延拡張の詳細については、すべての出力ヘルプページを参照してください。

Windowsコマンドプロセッサは、ループループ内のラベルをサポートしていません。ここでの解決策は、IFELSEを使用しています。

IFこれは、二重引用符が含まれていない文字列と二重引用符で囲まれた文字列であるため、条件が真になることはありません。文字列の比較には、周囲の二重引用符が必要ですが、コマンドIFで削除されません。環境変数iptempがための最初の上で定義されたため、コマンドブロックを解析する上で定義されていないされていないため、文字列の比較のために

IF条件はまた、構文エラーの理由です。これはための最も外側のが何行

if == "Packets: Sent = 1, Received = 0, Lost = 1 (100 loss)," (

をもたらし、このラインはもちろん、完全に間違っていることで実行される最初の時間になる前に、すでに%iptemp%を交換することになります。注:単一パーセント記号も削除されます。

比較する文字列のパーセント記号は、変数参照の先頭ではなく、リテラル文字として解釈されるためにもう1つのパーセント記号でエスケープする必要があります。エクスクラメーションマークが^^でエスケープする必要があり、最後のECHOラインで以下のコードで

は、変数名の区切りに、単純な文字リテラルから!の意味を変化させる有効にしているので、遅れ拡張のリテラル文字として解釈されますコマンドブロックを解析する際に、値を拡張せずに参照する必要があります。

@echo off 
setlocal EnableDelayedExpansion 
color b 
title Get Online IPs 
set "ListFile=IPlist.txt" 
if exist "%ListFile%" del "%ListFile%" 
for /L %%A in (0,1,255) do (
    for /L %%B in (0,1,255) do (
     for /L %%C in (0,1,255) do (
      for /L %%D in (0,1,255) do (
       set "IP=%%A.%%B.%%C.%%D" 
       for /F "delims=" %%i in ('%SystemRoot%\System32\ping.exe -n 1 !IP!') do set "iptemp=%%i" 
       if "!iptemp!" == "Packets: Sent = 1, Received = 0, Lost = 1 (100%% loss)," (
        echo !IP! is offline. 
       ) else (
        echo !IP! is online^^!>>"%ListFile%" 
       ) 
      ) 
     ) 
    ) 
) 
endlocal 

私のドイツ語のWindowsでは、文字列の比較は決して真実ではないため、すべてのIPは当然間違っています。

コンソールアプリケーションの終了コードを使用するほうがずっとよくなります。PINGは、pingが成功すると0、エラーが発生すると1になります。以前に実行されたコマンドまたはコンソールアプリケーションの終了コードは、XまたはXより大きいか等しいのチェック終了コード(エラーレベル)に応じてif not errorlevel Xとそれぞれif errorlevel Xと評価することができます。使用するコマンドを理解し、どのように彼らは、コマンドプロンプトウィンドウを開き、そこに次のコマンドを実行し、完全にページが非常に慎重に、各コマンドのために表示されているすべてのヘルプを読んで、仕事のため

@echo off 
setlocal EnableDelayedExpansion 
color b 
title Get Online IPs 
set "ListFile=IPlist.txt" 
if exist "%ListFile%" del "%ListFile%" 
for /L %%A in (0,1,255) do (
    for /L %%B in (0,1,255) do (
     for /L %%C in (0,1,255) do (
      for /L %%D in (0,1,255) do (
       set "IP=%%A.%%B.%%C.%%D" 
       %SystemRoot%\System32\ping.exe -n 1 !IP! >nul 
       if errorlevel 1 (
        echo !IP! is offline. 
       ) else (
        echo !IP! is online^^!>>"%ListFile%" 
       ) 
      ) 
     ) 
    ) 
) 
endlocal 

  • color /?
  • del /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • ping /?
  • set /?
  • setlocal /?
  • title /?

読むまた、Microsoftの記事:

0
for /L %%A IN (0,1,255) do (
    for /L %%B IN (0,1,255) do (
     for /L %%C IN (0,1,255) do (
      for /L %%D IN (0,1,255) do (
      set "flag=" 
      for /F "delims=" %%i in ('ping -n 1 %%A.%%B.%%C.%%D') do (
       if "%%i" == "Packets: Sent = 1, Received = 0, Lost = 1 (100% loss)," set flag=Y 
      ) 
      if defined flag (
       echo %%A.%%B.%%C.%%D offline 
      ) else (
       echo %%A.%%B.%%C.%%D >> IPlist.txt 
       echo %%A.%%B.%%C.%%D is online! 
      ) 
      ) 
     ) 
    ) 
) 

{テストされていない}

set %%A.%%B.%%C.%%D = IP 

環境変数0.0.0.0 スペースを設定します。.. 255.255.255.255 スペース "スペース IP" の値に スペースに重要です標準setの文で=演算子のの両方の演算子を使用すると、構文を逆にすることはできません。cmdは、ああ。

for /F "delims=" %%i in (iptemp.txt) do set "iptemp=%%i" 

は、ファイルの最後の行の内容にiptempの値を設定します。後のテストで選択した文字列と一致する可能性は低いです。

そして、あなたがの実行時の値にアクセスするために、「ブロック・ステートメント」

さらに、としては、SO回答数千の中で説明されている(文の括弧のシリーズ)、内のラベルを使用することはできませんブロック内で変数を使用するには、delayedexpansionモードを呼び出し、!var!を使用する必要があります。 (他の方法があります - これは最も簡単です)。 。iptempの際に定義されていないとして、「(この時点では期待できないた」実際に - %var%が、これはあなたのエラーレポートの源である、常にブロック文が

アン遭遇した変数の値であり、 cmd

if == "Packets: Sent = 1, Received = 0, Lost = 1 (100% loss)," (

としてこの行を解釈し、それの意味をなさないことができ、ブロックが遭遇する(及びそのブロックはfor /L %%A ...ブロックである)。

「IPオフライン」レポートでは、IPアドレスではなく「IPオフライン」と正確に言います。

改訂(しかし未テスト)コードは、ジャガイモの袋としてflagを使用し、にそれを初期化 - 囲む引用符は、任意の後続スペースがflag

に割り当てられた値に含まないあることを確認

for/fは、ping出力の各行のエンティティを順番に%%iに配信し、次に各行(現在は%%i)とあなたのマジック文字列を比較します(の両方とも面を引用する必要があります)flagに設定されています。マジック文字列がの場合は出力行と一致する場合は何でもとなります。

場合for/f仕上げ、flag電流値は、およびレポートの一方または他方が生成される(if defined現在値ではなく、初期値に作品があることに注意してください)と解釈されます。

関連する問題