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

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

新規登録して質問してみよう
ただいま回答率
85.35%
コマンドプロンプト

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

バッチファイル

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

Q&A

解決済

2回答

9564閲覧

バッチファイルでcallからgotoしてもメイン処理終了後にcallの残りの処理が行われる??

qaw

総合スコア9

コマンドプロンプト

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

バッチファイル

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

0グッド

0クリップ

投稿2021/10/10 05:48

前提・実現したいこと

Windowsバッチファイルのcall?goto?分についてです。
遅延環境変数が好きでないのでfor文の内容をサブルーチン(call)で処理してます。
その際分岐処理などで、gotoでおわらしてメイン処理に戻したのですが以下のようにメイン処理が終わったあとも処理が続きます。callしたくない場所の処理を行ったりと無茶苦茶。
バグ的な奴なんでしょうか?回避策を知ってる方、見つけた方は教えていただきたいです。

該当のソースコード

BATCH

1rem @echo off 2chcp 65001 3 4echo main_1 5call :sub_1 6echo main_2 7call :sub_2 8echo main_3 9:sub_end 10echo main_4_end 11pause>>nul 12exit /b 13 14 15:sub_1 16echo sub_1 17goto sub_end 18exit /b 19 20:sub_2 21echo sub_2 22goto sub_end 23exit /b

コンソール上の結果

Active code page: 65001 D:\>echo main_1 main_1 D:\>call :sub_1 D:\>echo sub_1 sub_1 D:\>goto sub_end D:\>echo main_4_end main_4_end D:\>pause1>>nul D:\>exit /b D:\>echo main_2 main_2 D:\>call :sub_2 D:\>echo sub_2 sub_2 D:\>goto sub_end D:\>echo main_4_end main_4_end D:\>pause1>>nul D:\>exit /b D:\>echo main_3 main_3 D:\>echo main_4_end main_4_end D:\>pause1>>nul D:\>exit /b D:\>

試したこと

sample.batをコマンドプロンプト上で実行しました。
callをgotoで抜けたとき、抜けた先の処理がexitで終了してもサブルーチンの処理が行われてcallで帰ってきた場合の処理も行われてしまっている。といった感じでしょうか、、、
gotoで抜けないようにするしかないのかなと思い質問させていただいた次第です。

補足情報(FW/ツールのバージョンなど)

Windows10のバージョンは21H1(OSビルド 19043.1237)

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

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

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

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

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

guest

回答2

0

ベストアンサー

gotoにサブルーチンから脱出する機能はありません。
お書きのコードは下記と同じです。

CMD

1@echo off 2chcp 65001 3 4echo main_1 5call :sub_1 6echo main_2 7call :sub_2 8echo main_3 9echo main_4_end 10pause>>nul 11exit /b 12 13:sub_1 14echo sub_1 15echo main_4_end 16pause>>nul 17exit /b 18 19:sub_2 20echo sub_2 21echo main_4_end 22pause>>nul 23exit /b

サブルーチンを終了して、呼び出し元に戻るのは、
exit /b
・ファイル末尾に到達(またはそれと同等のgoto :EOF
だけです。

サブルーチンから呼び出しのcallの直後以外に戻ることはできません。
どこにgotoしてもサブルーチン処理の中で、その次のexit /bや末尾への到達で、callの直後に戻ります。

どういう結果を期待していたのか書かれていませんが、

text

1main_1 2sub_1 3main_4_end 4(pause処理)

ですかね。そういう機能はCMDバッチスクリプトには無いです。

サブルーチンの中での条件判断に結果によって、呼び出し元に戻った時の処理を変えたいなら、exit /bで返り値を指定して、呼び出し元ではcallの直後でifで返り値により条件分岐します。

投稿2021/10/10 07:49

otn

総合スコア85901

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

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

cx20

2021/10/10 10:59

丁寧な解説参考になります。「:EOF」のことをすっかり失念していました。思い出させてくれてありがとうございます。
qaw

2021/10/11 02:34

すみません、期待した動作を書いてませんでしたがそれであってます。 ルーチン間でgotoを使うとメイン終了後にgotoを使ったルーチンの終了位置に戻ってしまう、、、勉強になりました。回避策ありがとうございます!!
otn

2021/10/11 04:32

> gotoを使うとメイン終了後にgotoを使ったルーチンの終了位置に戻ってしまう 「ルーチン間のgoto」は存在せず、gotoだけだとずっとサブのままなので、コード上にmain_4_endと書いてあろうがそこはサブルーチンの中ということです。メインとサブの行範囲がかぶっているだけ。
qaw

2021/10/12 01:24

あああ、なるほど納得です。 この場合、メイン処理の最後をexit /bではなくexit にして即終了させれば一応動かしたいように動くことに気づきました。
guest

0

callをgotoで抜けたとき、抜けた先の処理がexitで終了してもサブルーチンの処理が行われてcallで帰ってきた場合の処理も行われてしまっている

call と goto の違いですが、call は「行ってこい」、goto は「行け」となります。
したがってサブルーチン :sub_1 が終わった後は、後続の処理として main_2 が動きます。

図にするとこんなイメージです。

イメージ説明

<参考情報>
■ コマンドプロンプト - バッチファイルから別のバッチファイルを呼び出す(CALL)
https://www.javadrive.jp/command/bat/index12.html
■ Windowsコマンドプロンプト基礎文法最速マスター
https://github.com/cx20/basic-grammar-fastest-master-archives/tree/master/bat

投稿2021/10/10 07:01

cx20

総合スコア4648

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

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

ikapy

2021/10/10 09:30

M〇croS〇f〇のこの仕様は直観的でないので、linuxでの扱いと違いいつも好きになれません。 今回の説明でそうなのかと「ガッテン」です。 力作回答ありがとうございました。
cx20

2021/10/10 14:17

バッチファイルは相当レガシーな技術なので今どきの人は勝手が悪いと思うかもしれないですね。 そういえば、フリーソフトですが、バッチファイルをデバッグ実行するというツールを昔みかけました。 今回のようなバッチファイルであれば、ステップ実行して動作が確認できるかと思います。参考情報まで。 ■ 「VisualBat」バッチファイルの編集やデバッグを行う統合開発環境 - 窓の杜 https://forest.watch.impress.co.jp/library/software/visualbat/
qaw

2021/10/11 01:55

わかりやすい図までありがとうございます。。! visualbat、使ってみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問