5

バッチファイルの作成にあまり慣れていないので、おそらく何か間違ったことをしているのでしょうが、エコーのオフ/オンに本当に問題があります。(とはいえ、私が見逃した他のエラーがあれば、遠慮なく指摘してください)

これが私のコードの簡略版です:

@echo off
setlocal
set args=
set dir="."

:getargs
IF "%2"=="" (
    set dir="%1"
    goto callbatch
)
set args=%args% %1
shift
goto getargs

:callbatch
for %%f in (%dir%\*.txt) do (
    echo processing %%f
    "%BATCHHOME%\batch.bat %args% %%f
    echo
)

したがって、基本的に、単一のtxtファイルに対して何かを行うBATCHHOMEにバッチファイルがあり、特定のディレクトリ内のすべてのtxtファイルを処理するバッチファイルを作成したいと考えています。ループ内の唯一のエコーは、問題をよりよく説明するためのものです。

さて、ここで私は問題を抱えています。この出力は次のようになります。

processing foo\text1.txt
some output from batch.bat
ECHO is on.

C:\somedir>(
echo processing foo\text2.txt
   "C:\the\path\of\batch.bat" the arguments here foo\text2.txt
)
ECHO is on.

C:\somedir>(
echo processing foo\text3.txt
   "C:\the\path\of\batch.bat" the arguments here foo\text3.txt
)
ECHO is on.

(etc)

わかりました...呼び出しているバッチ ファイルがエコーをオンにする理由はわかりませんが、作成できなかったので、毎回オフに戻します。最後の部分を次のように変更しました。

:callbatch
for %%f in (%dir%\*.txt) do (
    echo processing %%f
    "%BATCHHOME%\batch.bat %args% %%f
    echo off
)
echo
echo on
echo
echo Finished!

(ここでも、デバッグ用に 2 つの "echo" が存在します) 出力は次のようになります。

processing foo\text1.txt
some output from batch.bat
processing foo\text2.txt
some output from batch.bat
processing foo\text3.txt
some output from batch.bat
(etc.)
ECHO is off.
ECHO is on.
Finished!

これでほぼ完璧ですが、少し変わったところがあります。エコーがオンの場合、「Finished!」と表示されるのはなぜですか? 「エコー終了!」の代わりに?ただし、より大きな (しかし関連する) 問題は、バッチ ファイルが完了すると、パスが表示されなくなることです。つまり、次の代わりに:

C:\Somedir>_

私はただ得る

_

パスを再度表示するには、「echo on」と手動で入力する必要があります。どこで私は間違えましたか?

編集:明確にするために、「エコー」自体がエコーの現在のステータスを出力することを認識しています。それが私が意図したことです。最初のコードでは、他のバッチ ファイルを呼び出した後、echo が不思議なことにオンになることを示しています。2 番目のものでは、バッチ ファイルの最後でエコーがオンになっていることを示していますが、動作はオンになっていないかのようです。それが私の問題です。

4

1 に答える 1

16

私は今あなたの問題を理解しています - そしてそれは興味深いものです。CALL を使用せずに、バッチ ファイル内からバッチ ファイルを呼び出しています。

バッチ A が CALL なしでバッチ B を実行すると、バッチ B が終了するとバッチ処理全体が終了します。バッチ A は中断したところから再開されません。バッチ処理が終了すると、ECHO 状態はバッチ処理が開始される前の元の状態 (通常はオン) に戻ります。

ただし、2 番目のバッチへの「呼び出し」が FOR ループ内にあるため、シナリオはもう少し複雑です。したがって、FOR ループは、バッチ処理が終了しても、メモリにキャッシュされた DO コマンドを実行し続けます。コマンドは、ECHO ON を使用してコマンド ライン コンテキストで実行されます。

2 番目のシナリオでは、FOR DO ブロック内で ECHO を明示的にオフにします。最初の「呼び出し」の後、再びコマンド ライン コンテキストに戻り、ECHO をオフにします。したがって、手動で ECHO ON にする必要があります。

FOR ループの後の行がどのように実行されるのかわかりません。あなたはコードを単純化したと言ったので、実際に実行しているコードには、ある種のコードブロックにもこれらの追加の行があると思います。その後、行はバッファリングされ、バッチ処理が終了した後でも実行されます。これは、「Finished!」と出力される行の理由も説明します。ECHO がオンになっていてもエコーされません。コード ブロック内のすべてのコマンドは、最も外側のコード ブロックに入る前に存在していた ECHO 状態を使用します。1 つの例外は、DO ブロックに入る前に存在していた ECHO 状態を使用する FOR DO ブロックです。

投稿したコードの両方のセットは、2 番目のバッチ ファイルを「呼び出す」行に不均衡な引用符があるため、実行されません。

修正は、2 番目のバッチ ファイルを実行するステートメントに CALL を追加するだけです。その後、バッチ処理が続行され、ECHO 状態はオフのままになり、親バッチは中断したところから適切に再開されます。

また、引数の解析ロジックと引用符の使用も改善しました。~独自の引数を明示的に追加する前に、各引数から引用符を削除する必要があります。引数には、すでに独自の引用符がある場合があります。また、ファイル名またはパスが引数として渡されるときはいつでも、スペースまたは特殊文字が含まれている場合は引用符で囲む必要があります。変数の値が引用符で囲まれているかどうかを追跡する必要があります。私は通常、変数の値を引用符で囲まないでおき、必要なときに明示的に引用符を追加する方が簡単だと思います。

@echo off
setlocal
set args=
set "dir=."

:getargs
IF "%~2"=="" (
    if "%~1" neq "" set "dir=%~1"
    goto callbatch
)
set args=%args% %1
shift
goto getargs

:callbatch
for %%f in ("%dir%\*.txt") do (
    echo processing %%f
    call "%BATCHHOME%\batch.bat" %args% "%%f"
    echo
)
于 2012-08-22T23:22:38.020 に答える