🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

Q&A

解決済

1回答

2337閲覧

コマンドプロンプトから得られる結果について

ayuzer

総合スコア15

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

0グッド

0クリップ

投稿2020/12/04 00:20

編集2020/12/04 00:33

コマンドプロンプトに貼り付けたコマンドが意図通りに実行されません。
どなたかご知見をお持ちでらっしゃる方がいらっしゃいましたら、ご教示ください。

***

Excelに列挙したIPアドレスに対して、文字列結合で以下のようなコマンドを作り、
コマンドプロンプトにコピー&ペーストで貼り付けると、
意図しない結果が返ってきてしまいます。

#コマンドは、Pingから返される標準出力に「バイト数 =32」という文字列が
含まれたら「成功」とechoし、含まれなかったら「失敗」とechoする単純な内容です。
下記は、ループバックアドレスは「成功」、「1.1.1.1」「2.2.2.2」は「失敗」となるはずが
echoされた結果が一つ目を除いてあべこべになってしまっています。

ping -n 1 127.0.0.1 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) ping -n 1 1.1.1.1 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) ping -n 1 127.0.0.2 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) ping -n 1 2.2.2.2 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) ping -n 1 127.0.0.3 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) *以下結果* C:\Users\isf00039>ping -n 1 127.0.0.1 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128 成功 C:\Users\isf00039>ping -n 1 1.1.1.1 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 成功 C:\Users\isf00039>ping -n 1 127.0.0.2 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.2 からの応答: バイト数 =32 時間 <1ms TTL=128 失敗 C:\Users\isf00039>ping -n 1 2.2.2.2 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 成功 C:\Users\isf00039>ping -n 1 127.0.0.3 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.3 からの応答: バイト数 =32 時間 <1ms TTL=128 失敗

何故このようなことが起こってしまうのでしょうか。

#「&」を使わず、ping と行とIFの行を分けると正しく表示されることから
「&」による1行記述に何かしら問題があるとにらんでいます。

#引数を外部テキストファイルに持ち、ループで実行すれば済むだけの話ではあるのですが
認識通りの挙動をしないため、正しい理解を得たく質問させていただいております。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/12/04 00:36

> コマンドプロンプトにコピー&ペーストで貼り付けると、 意図しない結果が返ってきてしまいます。 一気に実行した場合の話でしょうか?自分の手元で1つずつ実行した場合は特に問題なく実行されました。
ayuzer

2020/12/04 01:24

ご検証ありがとうございます。 1つずつ実行しても、おかしい結果が返ってきてしまいます。 ====================================== C:\Users\user>ping -n 1 127.0.0.1 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128 失敗 C:\Users\user>ping -n 1 1.1.1.1 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 成功 C:\Users\user>ping -n 1 127.0.0.2 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.2 からの応答: バイト数 =32 時間 <1ms TTL=128 失敗 C:\Users\user>ping -n 1 2.2.2.2 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 成功 C:\Users\user>ping -n 1 127.0.0.3 | find "バイト数 =32"&IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.3 からの応答: バイト数 =32 時間 <1ms TTL=128 失敗 ====================================== otn様よりご回答いただいた通り、%ERRORLEVEL%が行単位で解析されてしまうためであると 思われます。 maisumakun様の環境では問題無く実行されるとのことですが、 「1.1.1.1」や「2.2.2.2」が疎通するようなご環境で実行されたりは してませんでしょうか。
maisumakun

2020/12/04 02:00

> 「1.1.1.1」や「2.2.2.2」が疎通するようなご環境で実行されたりは してませんでしょうか。 えっと、1.1.1.1は通信可能です。 https://1.1.1.1/
ayuzer

2020/12/04 02:27

ご回答ありがとうございます。 私の環境では1.1.1.1へはPingが疎通しないため 環境の違いかと存じます。 ============================== C:\Users\user>ping 1.1.1.1 1.1.1.1 に ping を送信しています 32 バイトのデータ: 要求がタイムアウトしました。 要求がタイムアウトしました。 要求がタイムアウトしました。 要求がタイムアウトしました。 1.1.1.1 の ping 統計: パケット数: 送信 = 4、受信 = 0、損失 = 4 (100% の損失)、 ==============================
guest

回答1

0

ベストアンサー

%ERRORLEVEL%の変数の値への変換は、行単位の解析時点で行われますので、前行の実行後の値になります。

解決方法:

CMD

1REM % を使わず書く 2ping -n 1 127.0.0.1 | find "バイト数 =32"&IF ERRORLEVEL 1 (echo 失敗) ELSE (echo 成功) 3 4REM 行を変えて書く 5ping -n 1 127.0.0.1 | find "バイト数 =32" 6IF %ERRORLEVEL% EQU 0 (echo 成功) ELSE (echo 失敗) 7 8REM 「遅延環境変数展開」を使う(バッチファイルの場合) 9setlocal enabledelayedexpansion 10ping -n 1 127.0.0.1 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗)

1番目(ERRORLEVELが1以上なら条件成立)がお勧めです。

投稿2020/12/04 00:39

編集2020/12/04 00:48
otn

総合スコア85882

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2020/12/04 00:43

行単位と書きましたが、論理行の話なので、 for %%A in (~~~) do ( ~~~ ~~~ ) のように括弧を使った場合はこれ全体でまとめて解析されてその時点で%が展開されます。 (ループ実行前の値で展開される)
ayuzer

2020/12/04 01:10

非常に明瞭なご回答いただきありがとうございます。 ご指摘の通り、一つ目の方法で正しい結果を得ることができました。 ERRORLEVELの戻り値は0以外は曖昧なのでご教示いただいたような条件指定は忌避していたのですが なるほど、こういう場面では役立つのですね。 ただ、遅延環境変数展開を用いた方法で試すと、全ての結果が「失敗」となってしまいました。 これについては何かお心あたりございますでしょうか。 #趣旨を逸れてしまい申し訳ございません・・・。
otn

2020/12/04 13:45

> ERRORLEVELの戻り値は0以外は曖昧なので if errorlevel 1 は、if %ERRORLEVEL% NEQ 0 と同等なので、曖昧なことは無いです。 > ただ、遅延環境変数展開を用いた方法で試すと、全ての結果が「失敗」となってしまいました。 setlocal enabledelayedexpansion を書きましたか?
ayuzer

2020/12/07 11:14

ご返信遅くなり申し訳ございません。 > if errorlevel 1 は、if %ERRORLEVEL% NEQ 0 と同等なので、曖昧なことは無いです。  失礼しました。読み違えをしておりました。  「1」以上はTRUE という条件式で、仰る通り曖昧さの無い指定であると理解します。 > setlocal enabledeleyedexpansion はい、記載しましたが、以下の通り全て失敗となってしまいました。 遅延展開でも、&で1行に記載してしまうの何かしら支障が出るものなのか、 私の環境固有の問題なのか、判別はできず・・・。 ************************** Microsoft Windows [Version 10.0.14393] (c) 2016 Microsoft Corporation. All rights reserved. C:\Users\user>setlocal enabledelayedexpansion C:\Users\user>ping -n 1 127.0.0.1 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128 失敗 C:\Users\user>ping -n 1 1.1.1.1 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 失敗 C:\Users\user>ping -n 1 127.0.0.2 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.2 からの応答: バイト数 =32 時間 <1ms TTL=128 失敗 C:\Users\user>ping -n 1 2.2.2.2 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 失敗 C:\Users\user>ping -n 1 127.0.0.3 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.3 からの応答: バイト数 =32 時間 <1ms TTL=128 失敗 C:\Users\user>
otn

2020/12/07 11:19

ああ、バッチファイルに書いたんじゃ無くて、直接コマンドプロンプトに打ち込んだんですね。 それではsetlocalが効きません。 確かに「コマンドプロンプトに貼り付けたコマンドが」と書いてありましたね。失礼。 cmd /v:on と、cmd.exeを起動して、その中でやってください。v:on で遅延環境変数展開オンです。
ayuzer

2020/12/07 23:39

こちらこそ知見が浅く申し訳ありません。 ご教示いただいた通りに実行しましたところ、正しい結果を得ることができました。 ERRORLEVEL変数は行毎に評価される、 IF ERRORLEVEL~の書き方であれば行毎の制約に捉われない、 コンソールで遅延環境変数展開を使いたい場合は /v:on を使うなど、 知らなかった知識を色々と得ることができ大変感謝しております。 ありがとうございました。 **** REM 参考:結果 C:\Users\user>cmd /v:on Microsoft Windows [Version 10.0.14393] (c) 2016 Microsoft Corporation. All rights reserved. C:\Users\user>ping -n 1 127.0.0.1 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128 成功 C:\Users\user>ping -n 1 1.1.1.1 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 失敗 C:\Users\user>ping -n 1 127.0.0.2 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.2 からの応答: バイト数 =32 時間 <1ms TTL=128 成功 C:\Users\user>ping -n 1 2.2.2.2 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 失敗 C:\Users\user>ping -n 1 127.0.0.3 | find "バイト数 =32"&IF !ERRORLEVEL! EQU 0 (echo 成功) ELSE (echo 失敗) 127.0.0.3 からの応答: バイト数 =32 時間 <1ms TTL=128 成功
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問