質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.33%
バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

解決済

2回答

651閲覧

バッチファイルでnslookup実施時にコマンドプロンプト画面に出力させない、全IP取得方法

y_daruma

総合スコア1

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

0クリップ

投稿2025/02/02 13:18

編集2025/02/02 13:21

実現したいこと

・バッチファイルでnslookupでurlからIPアドレスを取得したい。
・取得した結果を変数化したい。

発生している問題・分からないこと

・「@echo off」にしているが下記のようにコマンドプロンプト画面に表示されてしまう。
コマンドプロンプト画面に表示させないようにしたい。
出力例①:*** dns.google がxxxx.xxxx.jp を見つけられません: Non-existent domain
出力例②:権限のない回答:

・nslookupの結果からIPアドレスが2つ取得した場合に両方とも利用したい。
下記出力イメージだと、111.222.333.444、555.666.777.888を変数に入力したい。
出力例:
サーバー: dns.google
Address: 8.8.8.8

権限のない回答:
名前: aaa.bbbb.jp
Addresses: 111.222.333.444
555.666.777.888

該当のソースコード

@echo off setlocal enabledelayedexpansion set "DNS_SERVERS=8.8.8.8 8.8.4.4" set "LOG_FILE=log.txt" rem 複数のDNSサーバで名前解決を試みる set "DNS_SUCCESS=0" rem パラメータ初期化 set "IP_ADDRESSES=" for %%d in (%DNS_SERVERS%) do ( for /f "skip=1 tokens=2 delims=:" %%j in ('nslookup !HOST! %%d ^| findstr /r /c:"Address"') do ( if "%%j" NEQ " " ( echo --------->> %LOG_FILE% echo %%j >> %LOG_FILE% echo %%j | findstr /v "権限のない回答" > nul if !errorlevel! == 0 ( set "DNS_SUCCESS=1" if "!IP_ADDRESSES!" == "" ( set "IP_ADDRESSES=%%j" echo --------->> %LOG_FILE% echo !IP_ADDRESSES!>> %LOG_FILE% ) else ( set "IP_ADDRESSES=!IP_ADDRESSES! %%j" echo --------->> %LOG_FILE% echo !IP_ADDRESSES!>> %LOG_FILE% ) ) ) ) )

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

copilotで試してみたが回答が得られなかった。

【前提】
・windowsのOSはwindows10、またはwindows11を利用する。
・PowerShellは使わない。
・バッチファイルで下記のやりたいことを実装したい。

【やりたいこと】
・for文の中でgoto分を利用するとエラーになるためgoto文を使わないやり方にしたい。
・callでの呼び出しは使わないやり方にしたい。
・exitではなくbreakでfor文を抜けるようにしたい。
・nslookupで複数IPアドレスが取得できた場合は、取得できたIP全てに対して利用したいコマンドを処理したい。
・nslookupの結果をAddressで絞った場合、1行目はDNSのIPアドレスになることを考慮してほしい。
・nslookupの結果でAddressで絞るとAddressが行にないIPアドレスが漏れてしまうことを考慮してほしい。

補足

特になし

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

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

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

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

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

yambejp

2025/02/03 03:42

プロセスが重要なのでしょうか?それとも結果が重要なのでしょうか? コマンドプロンプトという制限の多い環境で高次元の処理は賢明とは言い難いです
y_daruma

2025/02/03 07:14

プロセスが重要で、IPアドレスの取得が優先です。 画面への表示は重要では無いですが、可能であればの範囲です。
yambejp

2025/02/03 07:22

そうなると基本は「>」でリダイレクトした文字列から該当部分を抽出することになるでしょうね grep系のコマンドも使わない前提でしょうから無理やりやることになりそうですから頑張ってとしか・・・
y_daruma

2025/02/03 10:31

コメントありがとうございますm(__)m
Ripple.N

2025/02/04 01:38

他の質問にも関連すると思いますが プロセスが重要ならばなぜPowershellを使わないという制限を加えるのでしょうか? 何らかの理由でPowershellが使えないと判断したならばそちらを解決し Powershellを使ったほうがうまくいきそうな気がします。
dodox86

2025/02/04 01:58

たぶんですが、ここで言う「プロセスが重要」とはcmd.exeでのバッチファイル、Windows標準の外部コマンド以外は使わないという過程(<プロセス)が重要、必須条件で、IPアドレス部分のみ取得をしたいということなのでしょうね。(個人的には無理ゲーな気がするので静観です)
y_daruma

2025/02/04 14:04

>Ripple.N 条件に記載ができておらず失礼しました。 PowerShellの利用が制限されている環境で実装したいためです。 制限は解除ができないためバッチファイルだけでの実装を検討しています。
y_daruma

2025/02/04 14:06

>dodox86 コメント頂いた通り単純にバッチファイルだけの機能を利用してIPアドレス部分だけを取得したいです。 スキル不足で申し訳ございません、そもそも仕組み上無理なことをやろうとしているのでしょうか?
break_tat

2025/02/04 15:51

何ここのコメントしてる人達説教だけして回答してやらんのや、笑える
break_tat

2025/02/04 16:00

このサイトってオープンコミュニティで経験、知識がある人がコメントするんでしょ 相手に対しての自己満な質問とか、無理ゲーとか言ってる人は黙ってたらw
break_tat

2025/02/04 16:52

頑張ってとか、powershellとか、無理ゲーってスキルが無いんでしょ?質問する意味なんなん? スキルあるならこの質問者他でも投稿してるから回答してあげたら? https://teratail.com/questions/r1d7oc5f7v7gsj
yambejp

2025/02/05 00:07 編集

TO:break_tat 「スキルが無いんでしょ?」「黙ってたらw」 完全に同意します
break_tat

2025/02/07 00:07

yamgejp 分かってんじゃん! 他でもやってる自己満な質問者を問い詰める事止めたら? その方がこのサイトも意味があるサイトになるし、あなたの評価もあがるんじゃないの? それとも説教したり問い詰めるのに悦に入ってる感じ? owl_hackのコメントも見たら?
guest

回答2

0

ベストアンサー

答えを書くだけがいい回答とは言えませんし、偉そうなことを言って不快に思われたら申し訳ないのです。

私自身も勉強中で、いつも参考にさせて頂いています。

色々な方がいらっしゃるので、回答に繋がらないのであればあえてスルーでもいいとも思うこともあります。
ただこのサイトは他でも「上から目線の回答」と書かれているぐらい評判も悪かったりします。
個々人が行動規範を理解してコメントすべきだと思います。

行動規範にチェックを入れているのであれば、質問者・回答者ともにコメントを記載している人は、全員個々人の投稿内容と行動規範を再度読み直したほうがいいと思います。

質問されてる方は相手を思いやってますか?
質問者に対して何を求めているのかを分かるように伝えてあげてはいかがでしょうか?質問するだけして回答もせず、解決策につながらない質問をすることは行動規範にあっているのでしょうか?

回答された方も質問の回答につながる回答になってますか?
否定・寄り添っていない・思慮の足りないコメントではなく、「アドバイス・解決策につながるコメント」を追加で記載してはいかがでしょうか?そのほうが行動規範に沿った回答だと思います。

ざっと作ったのできれいなコードではありませんが、下記のやり方で実現できるのではないでしょうか。

@echo off
cls
set "DNS_SERVERS=8.8.8.8 8.8.4.4"
rem set "DNS_SERVERS="
set "HOST=yahoo.co.jp."
set "LOG_FILE=log.txt"
set "IP_FILE=nslookup_ip.txt"
rem 複数のDNSサーバで名前解決を試みる
set "DNS_SUCCESS=0"
rem パラメータ初期化
set "IP_ADDRESSES="
rem 出力ファイル名用カウンタ
set "count_check=1"
setlocal enabledelayedexpansion
for %%d in (%DNS_SERVERS%) do (
nslookup !HOST! %%d>nslookup_[!count_check!].txt 2>&1
set /a count_check=!count_check!+1
)
set loop_count_01=1
:loop_01_start
if !count_check! equ !loop_count_01! (
goto loop_01_end
)
set nslookupfile=nslookup_[!loop_count_01!].txt
set skip_count=1
for /f "tokens=1,* delims= " %%f in ('type !nslookupfile! ^| findstr "Address"') do (
set a=%%f
set ip_01=%%g
if !skip_count! neq 1 (
echo !ip_01!>>!IP_FILE!
)
set skip_count=!skip_count!+1
)
set /a loop_count_01=!loop_count_01!+1
goto loop_01_start
:loop_01_end
echo --->>!IP_FILE!
set loop_count_02=1
:loop_02_start
if !count_check! equ !loop_count_02! (
goto loop_02_end
)
set nslookupfile=nslookup_[!loop_count_02!].txt
set skip_count=1
for /f "tokens=1,* delims= " %%h in ('type !nslookupfile! ^| findstr /v "権" ^| findstr /v "サ" ^| findstr /v "Add" ^| findstr /v "名前"') do (
set a=%%h
echo a=!a!
set ip_02=%%i
echo !ip_02!>>!IP_FILE!
set skip_count=!skip_count!+1
)
set /a loop_count_02=!loop_count_02!+1
goto loop_02_start
:loop_02_end
endlocal
exit

投稿2025/02/05 01:44

owl_hack

総合スコア11

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

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

y_daruma

2025/02/06 14:41 編集

実際に試してみて求めていたことが実現できました! 繰り返しの部分は自分でリファクタします、ありがとうございましたm(__)m
break_tat

2025/02/07 00:00 編集

色々大変だろうけど頑張って
owl_hack

2025/02/07 00:03 編集

私自身このサイトで色々勉強させてもらっています。 質問する人がどう思っているかを考えて投稿してみました。 リファクタポイントは色々あると思いますので試してみてください。
break_tat

2025/02/07 00:27

ん?なんか一瞬owl_hackとのコメントが逆転して表示された?(気のせいか
guest

0

・「@echo off」にしているが下記のようにコマンドプロンプト画面に表示されてしまう。
コマンドプロンプト画面に表示させないようにしたい。

まず、echo offの機能の誤解があります。echo offはコマンドの出力結果を画面に表示するかどうかには無関係です。「コマンドラインそのもの」を表示するかどうかです。

権限のない回答:などが画面に表示されるのは、それらが「標準出力」でなく「標準エラー出力」に出力されるからです。
パイプで次段に渡ったり、for /fで取得出来るのは「標準出力」です。
「標準出力」、「標準エラー出力」についての理解がないのならそれらについて学べば、解決法も自明となります。
CMD.EXEの特殊記号> &が関連するのでその点は注意ですが、パイプを^|とお書きなので、そこはご存じなのかもしれません。

2つ目以降のIPアドレスは、Addressという文字列のある行の次の行から表示されますが、
findstr /r /c:"Address"してしまうと、それらの行が取得出来ないので、処理ロジックを考え直す必要がありますね。
「行頭が空白文字の行を取得」とかでいいかもしれませんが、for /fのオプション含めて再考が必要です。

あとtokens=2 delims=:ということはIPv6アドレスはあり得ない前提ですかね。

・for文の中でgoto分を利用するとエラーになるため

「中から外へのgoto」は問題ありません。
「外から中へ」「中から中へ」は駄目ですが、その場合でもgoto文自体は文法エラーではないです。

・breakでfor文を抜けるようにしたい。

そんな機能はありません。forを抜けるならgotoかexit /bで。

バッチスクリプトに限らず、普通のプログラミング言語でも同じですが、「対象言語を理解しないままでのコピペ」で出来る範囲を超えている題材だと思いますよ。

投稿2025/02/04 05:24

編集2025/02/04 05:26
otn

総合スコア86167

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

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

y_daruma

2025/02/04 14:33

回答ありがとうございます。参考になりました。
break_tat

2025/02/04 15:53

ここのスレ説教スレなん? 質問も回答も説教だけやんマジ笑える 回答できんなら書くなや
otn

2025/02/05 00:28

回答してますけど??? 問題発生の原因と、「こういう方針で進めば解決できる」を書いたのですが、読み取れませんか? PowerShell等を言ってる人も、質問者の目的が、 ・問題解決が目的なので、たまたまBATでやり始めたがそれに固執しない ・他のツールが良いのはわかるが、BATの学習目的も兼ねているので是非BATでやりたい のどちらかで、考えるべきことが違うので、『問題解決目的なら他のツールが良い」と言ってるのでしょう。そのあたりは読めば自明かと思ってましたが、自明でない方もいるのは、まあ、そうでしょうね。 私は「面倒くさいけど、こういうのをBATで書けるようになりたいなら、出来ない話ではない」ので、BATで回答しています。 その後のコメントで、「BATの学習目的も兼ねている」訳ではではなさそうので、別途コメントします。
otn

2025/02/05 01:07 編集

> PowerShellの利用が制限されている環境で実装したいためです。 これは具体的にどういうことでしょうか? (1) 組織のルールで「PowerShellは使用禁止」と明示的に言われている (2) そう言われているわけではないが、powershell -file AAAA.ps1 のように実行すると「このシステムではスクリプトの実行が無効になっているため」のようなメッセージが出る (1)なら責任者と個別交渉するか、Powershellを諦めるかの二択。 (2)なら powershell -ExecutionPolicy remotesigned -file AAAA.ps1 等で可能なはずです。長いのでそういう1行だけのBATファイルを作る。 組織の方針が不明なら、確認しましょう。 PowerShellなら外部コマンドnslookupを呼び出さずとも、Resolve-Dnsname という名前のままの内蔵コマンドがあります。複数アドレスも問題なし。コマンドの結果はオブジェクトなので、そこからIPv4アドレス方法だけ抜き出して、変数に格納か、あるいは、そのままパイプでforeach-objectでIPアドレスを使うコマンドを起動するか。
otn

2025/02/05 09:30 編集

PowerShell の Resolve-Dnsname を使えば簡単に出来ると思ったのですが、名前がDNSサーバーで見つかったときは確かに簡単ですが、見つからない名前の時にエラーメッセージが出ます。 「エラーメッセージ出力抑止」みたいなことをしないといけないとなると業務では面倒ですね。 (DNSサーバーと通信できないというエラーメッセージも抑止されてしまうので、事前にそういうエラーがないかをチェックする必要がある) Resolve-Dnsname のオプションで見つからないときの処理を指定できると良いのですが。 まあ、利用目的によって「見つからない名前を指定する事は無い」という前提があれば問題なし。
y_daruma

2025/02/06 14:40

追加コメントありがとうございます。 powershell自体の利用が禁止されているため(1)/(2)両方ともできません、そのためバッチのみでの実装しかできません。 powershellではコメント頂いたようなことが簡易にできるため利用できるといいのですが。
otn

2025/02/06 14:48

そうでしたか。明示的に禁止されているケースは初めて聞きました。Powershell -file ~~ だけでは実行できないので使えないと誤解していた質問者はいたのですが。 利用目的が書いてないので、「正常にIPv4アドレスのみが取得出来る以外あり得ない」という前提を置いて良いのかどうかが不明で、具体的なコードを書くのをためらってました。 コメントに書いたようにPowerShell の Resolve-Dnsname でも「名前が見つからないケース」をどうすれば「スマートに」処理できるのか私も分かりません。nslookupの出力を解析するなら、各種パターンの出力を見てそれに合わせてifで分岐すればどうにでも出来るのですが。 質問に書かれた事象が何故発生したのかの理由の説明はしましたので、その点を理解されたのであれば、幸いです。今後は自力で解決できると思います。
y_daruma

2025/02/06 15:18

ありがとうございます。
break_tat

2025/02/07 00:19 編集

回答って、質問者のコードの説明すること??? 質問者のコードを見て、どこがおかしいからこういう考え直したらで動くってことが回答じゃないの? 「バッチファイルで」ってプロンプトにも書いてある投稿に対して「PowerShell」を推すこと自体が意味分からん。 今回みたいに「(owl_hackのコメントのみある)上から目線のアドバイス」で思い込みで回答したら、今回みたいに質問者の知りたいことじゃない回答になるんじゃないの? ちなみにpowershellなんて制御されている企業多いよ、特に顧客情報取扱ったり、セキュリティに厳しい会社だと。 しかもBypassなんて最強権限なんて↑の会社じゃぜってい無理でしょw ちなみにググったらfor文をbreakで抜けるって書いてるサイトあるね、間違ってるけど。 「対象言語を理解しないままでのコピペ」って書いてるけど質問者もそれ調べてんじゃないの https://yoiegao.net/windows%E3%83%90%E3%83%83%E3%83%81%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%A7%E6%A5%BD%E3%82%92%E3%81%99%E3%82%8B%EF%BC%9A%E3%83%90%E3%83%83%E3%83%81%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%A7for/ まあどう考えてるか分からんけど質問者にアドバイスしたいのか、回答をしてあげるのかは分けた方がいいよ。 俺もotnのコメントみて勉強になってることもあるし、ただ今回のような回答者が求めていない回答は止めたら?
otn

2025/02/07 18:00

> どこがおかしいからこういう考え直したらで動くってことが回答じゃないの? はい。そういう風に書いてますよ。 > 「バッチファイルで」ってプロンプトにも書いてある投稿に対して「PowerShell」を推すこと自体が意味分からん。 それもすでにコメントに書きましたが、質問目的が、 ・DNS参照するという目的を達成したい ・自力でこういうコードが書けるようになりたい が不明で、「DNS参照が最優先」を想定するなら制約をすてて簡単な道を示すのも回答だと思います。質問文に「組織でPowerShellが禁止されている」とは書いてないので。 一般論でいうと「簡単な手段があるのに、困難な手段をとろうと苦労している質問者」に対して、困難な道を歩く方向で回答するのか、簡単な手段があるよと教えるのと、どっちが質問者のためになるかということです。 (ただし、コメントに追加したように、PowerShell の Resolve-Dnsnameでエラーケースをどうしたら良いのか今の私にはよくからないので、場合によってはnslookupの出力を解析する必要があるかもしれず、そうだとすると、PowerShellかバッチスクリプトのどっちが楽かは慣れの問題かも知れませんので、「PowerShellが楽」と即断して良いものか分かりません) なお、コメントで「組織でPowerShellが禁止されている」という真相が明かされてからは、「Powershellを使いましょう」と書いている人はいないと思いますよ。 一方私の回答は、「バッチファイルでnslookupでurlからIPアドレスを取得したい。」と手段を限定していることからして、 ・自力でこういうコードが書けるようになることが目的 を前提に、「これこれが問題発生の原因なので、こういう方向で考えれば解決できる」と回答してます。 質問者の中には、「自力で解決できるように自分を向上する意思はない。(コピペで動く)回答だけ書いてくれ」が望みだと思える人もいますが、今回はそうでは無いと思ったので(この後のreakの項参照)。 それが誤解だったら済みません。 > ちなみにpowershellなんて制御されている企業多いよ、特に顧客情報取扱ったり、セキュリティに厳しい会社だと。 「一般の会社のOA用PC」や、「業務専用PCをその業務以外で使用の場合」の話でしょうか? 業務システムの中では色々なプログラミング言語で書かれたプログラムが動いています。Powershellも例外ではありません。 このサイトはIT技術者が質問するサイトなので、過去の質問で「明示的にPowerShellが禁止されているので使えない」と明記された質問は記憶には無いです。私が全質問を見ているわけじゃないし、見たけど忘れてしまっている可能性もるので、実際になかったとまでは言えませんが。 オプションを毎回指定しないといけないので、禁止されているのではないかと推測している人はいたと思います。担当部門に問い合わせた結果が「Powershell実行禁止」だったのか「デフォルトを変更しなければ実行してOK」だったのか不明。 今回は「powershell自体の利用が禁止されている」ということなので、業務システムの中で動く運用支援ツール的な物を作る話ではなくて、自分のOAPCでこういうことをやってみたいという話だったのかも知れませんね。 自PCでちょっとDNS参照をやってみるだけならnslookupの出力を目で見て解釈すれば良いので、それをスクリプトにするという時点で、システム構築からみの案件だと思いました。 breakについては、他の言語でのプログラミングが出来る人で、その言語のつもりでうっかり書いてしまった物かと思っていました。なので、バッチスクリプトの文法を理解すれば自力で書けるのかと。 まあこれは想像なので、break_tatさんのお書きのサイトを見て疑わずに信じたのが真相である可能性もあります。 (breakで抜けられると書いてあるサイトがあるとは想像できなかったので、その発想は無かった) forの()の中でのgotoについては、知らないで書くと何らかのエラーになることが多いだろうから、それを「gotoがエラーになった」と解釈したのだと思っています。これについては公式リファレンスと言える`for /?`にも`goto /?`にも書いてないので、誤解してもしょうがない。私もMSのサイトに説明が無いので、実験してみて理解しました。 質問文に書いてないことは、1つずつ全部質問するか、全体の書きぶりから「多分こうだろうな」と推測するかどちらかしか無いわけで、推測が間違ったことを責められてもなあと思いますね。 「あなたは成長を望まず答えだけ欲しいのですか?それとも自力で解決出来るようになりたいのですか?」と毎回聞かないといけないとすると結構大変です。質問フォームの区分にあると良いのかも。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.33%

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

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

質問する

関連した質問