糟糕——这个问题几乎不可能完美解决,原因如下:
1)批处理文件可能被多种机制“调用”:
CALL scriptName
管道,例如:scriptName | findstr ...
FOR /F,例如:for /f ... in ('scriptName ...') do ...
CMD,例如:cmd /c scriptName ...
或%comspec% /c scriptName
开始,例如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 会找到所有“调用”,因为调用本身可能会被隐藏在后面一个变量。