0

現在のビルド システムは、「マスター」バッチ ファイルから呼び出される大量のバッチ ファイルです。「マスター」バッチ ファイルから呼び出されるすべてのバッチ ファイルを見つけるにはどうすればよいですか?

残念ながら、リポジトリには他の多くのバッチ ファイルも含まれており、作業コピー内のすべてのバッチ ファイルを一覧表示することはできません。

実際の実行を「シミュレート」することはあまり気にしません。マスター バッチ ファイルから呼び出される可能性のあるすべてのファイルのリストを取得できれば問題ありません。

299 個のファイルがあるので、各ファイルに echo "" を追加したくありません。

参照されるバッチ ファイルは、「call xyz.bat」、つまり相対パスを使用して呼び出されます。ただし、次のように、バッチ ファイルによって現在の作業ディレクトリが変更されることがあります。

cd client
call mk.bat
cd ..

また

pushd client\install
call prepare.bat
popd

編集:例を追加

4

2 に答える 2

2

うん、いくつかの理由から、この問題を完全に解決することはほとんど不可能です。

1) バッチ ファイルは、複数のメカニズムによって「呼び出される」場合があります。

  • CALL scriptName

  • パイプ、例えば:scriptName | findstr ...

  • FOR /F 例:for /f ... in ('scriptName ...') do ...

  • CMD、たとえば:cmd /c scriptName ...または%comspec% /c scriptName

  • たとえば、STARTstart "" scriptName ...

2) 上記の構造のいずれかが、バッチ スクリプトへの「呼び出し」でなくても存在する可能性があります。たとえば、CALL を使用して、ラベルを呼び出したり、コマンドを実行したりできます。FOR /F を使用して文字列を解析できます。等

3) どの「呼び出し」メカニズムが使用されていても、「呼び出し」ターゲットは文字列リテラルではなく変数で表すことができます。例えば:

set "myScript=ScriptName"
REM the SET may not be anywhere near the CALL
call %myScript%

4) スクリプト名とパスがコードに表示されない場合があります。ファイルシステムから動的に読み取るか、ロジックを介して派生させることができます。

5) 実際の呼び出し自体が変数に値として埋め込まれている場合があります。これは、どの呼び出しメカニズムにも当てはまります。例えば:

set "myCommand=CALL"
%myCommand% ScriptName

6) 質問で指摘したように、スクリプトへのパスは相対パスである可能性があり、スクリプトは現在のディレクトリを変更する可能性があります。または、「呼び出し」が PATH 環境変数に依存している可能性があります。

7) 「呼び出された」スクリプトは、それ自体で別のスクリプトを「呼び出す」ことができます。


FINDSTR を使用して任意の呼び出しメカニズムを探すことができ、ほとんどの "呼び出し" が見つかる可能性があります。しかし、多くの偽陽性が発生する可能性があります。スイッチを追加して、/N一致する各行の前に行番号を付けることができます。次に、テキスト エディターで一致する各行を手動でチェックして、関心のある「呼び出し」であるかどうかを確認する必要があります。

findstr /nir /c:"\<call\>" /c:"|" /c:"for  */f " /c:"\<cmd\>" /c:"\<%comspec%\>" /c:"\<start\>" *.bat

非常に多くの誤検知がある可能性があるため、スクリプト全体のロジックを手動でトレースした方がよい場合があります :-( FINDSTR がすべての「呼び出し」を見つけるという保証はないため、これは特に当てはまります。呼び出し自体が背後でマスクされる可能性があるためです。変数。

于 2013-02-15T12:19:32.193 に答える
1

各バッチ ファイルの先頭にログを追加できます。あなたがしたくないと言ったのは知っていますが、あなたが思っているほど難しくはありません.

@echo off
:: addlogging.bat patch|unpatch
::
:: addlogging.bat patch
::    finds every .bat file in the current directory and every subdir
::    beyond, and patches each, prepending an echo to a log file
::
:: addlogging.bat unpatch
::    finds every .bat file in the current directory and every subdir
::    beyond, and removes the logging patch

setlocal

if #%1==#patch goto next
if #%1==#unpatch goto next
goto usage

:next
for /f "delims=" %%I in ('dir /s /b *.bat') do (
    if not "%%I"=="%~f0" (
        if #%1==#patch (
            set /p I="Patching %%I... "<NUL
            echo @echo %%time%% %%~f0 %%* ^>^> "%%userprofile%%\Desktop\%%date:/=-%%.log">"%%~dpnI.tmp"
        ) else (
            set /p I="Unpatching %%I... "<NUL
        )
        findstr /v "^@echo.*time.*~f0.*>>" "%%I">>"%%~dpnI.tmp"
        move /y "%%~dpnI.tmp" "%%I">NUL
        echo Done.
    )
)
goto :EOF

:usage
echo usage: %~nx0 patch^|unpatch
于 2013-02-15T14:35:52.670 に答える