我们当前的构建系统是从“主”批处理文件调用的大量批处理文件。如何查找从“主”批处理文件调用的所有批处理文件?
不幸的是,存储库还包含许多其他批处理文件,我不能只列出工作副本中的所有批处理文件。
我不太关心“模拟”真正的执行。如果我得到一个可能从主批处理文件调用的所有文件的列表,那就没问题。
有299个文件,所以我不想在每个文件中添加一个回音“”。
使用“call xyz.bat”调用引用的批处理文件,即相对路径。有时批处理文件会改变当前的工作目录,如下所示:
cd client
call mk.bat
cd ..
或
pushd client\install
call prepare.bat
popd
编辑:添加了示例
答案 0 :(得分:2)
Yuck - 由于以下几个原因,这个问题几乎不可能完全解决:
1)批处理文件可以通过多种机制“调用”:
CALL scriptName
管道,例如:scriptName | findstr ...
FOR / F,例如:for /f ... in ('scriptName ...') do ...
CMD,例如:cmd /c scriptName ...
或%comspec% /c scriptName
START,例如start "" 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会找到所有“调用”,因为调用本身可以被隐藏在变量后面。
答案 1 :(得分: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