问题
I need to have my 2.bat
script behaviour depending on the name of calling script.
Scenario:
2.bat
is invoked from many other external scripts, which I am not entitled to change. Only 2.bat
is under my thumb.
1.bat
:
...
call 2.bat
2.bat
:
...here place something extracting "1.bat"...
回答1:
As you cant change the calling bat there will be almost impossible to get its name if it is triggered through the cmd console (may be a memory dump could help?) as then the ProcessId will hold information only for the cmd.exe
. The command prompt history could give you some information but it would be unreliable (and requires a dump to a temporary file)
If the calling bat is double clicked you can use this:
setlocal enableDelayedExpansion
for /f "tokens=2* delims= " %%a in ("%cmdcmdline%") do (
if /i "%%~a" equ "/c" (
for %%# in (%%~b) do (
echo calling bat : %%~#
)
) else (
doskey /history >"%tmp%\cmd.history"
for /f "usebackq tokens=* delims=" %%# in ("%tmp%\cmd.history") do (
set "last_command=%%#"
)
echo probably this is the calling bat: !last_command!
del /q /f "%tmp%\cmd.history"
)
)
pause
回答2:
You can get the name of a calling batch with a trick.
Assuming you have a first.bat
(you can't controll) it could look like this
@echo off
set caller=empty
echo This is %~0
for /L %%n in (1 1 3) do (
echo(
echo #1 before calling, n=%%n
call second %%n
)
echo Back to %~0
And your second.bat
detects the caller
@echo off
setlocal DisableDelayedExpansion
set "func=%~0"
for /F "delims=\" %%X in ("%func:*\=%") do set "func=%%X"
if ":" == "%func:~0,1%" (
goto %func%
)
REM *** Get the name of the caller
(
(goto) 2>nul
setlocal DisableDelayedExpansion
call set "caller=%%~f0"
call set _caller=%%caller:*%%~f0=%%
if defined _caller (
set "callType=batch"
call "%~d0\:mainFunc\..%~pnx0" %*
) ELSE (
set "callType=cmd-line"
cmd /c "call "%~d0\:mainFunc\..%~pnx0" %*"
)
echo BACK
endlocal
)
echo NEVER REACHED
exit /b
:mainFunc
echo :mainFunc of %~nx0 arg1=%1 is called from '%caller%'/%callType%
exit /b
回答3:
I've adjusted jikou's and jeb's code a little bit so it can also detect the caller function from the caller script.
detectCallerScript.bat:
@echo off
setlocal DisableDelayedExpansion
set "func=%~0"
for /F "delims=\" %%X in ("%func:*\=%") do set "func=%%X"
if ":" == "%func:~0,1%" (
goto %func%
)
REM *** Get the name of the caller
(
(goto) 2>nul
setlocal DisableDelayedExpansion
call set "caller=%%~f0"
call set _caller=%%caller:*%%~f0=%%
if defined _caller (
set "callType=batch"
call "%~d0\:mainFunc\..%~pnx0" %%0 %*
) else (
set "callType=cmd-line"
cmd /c "call "%~d0\:mainFunc\..%~pnx0" %%0 %*"
)
endlocal
)
echo(NEVER REACHED
exit /b
:mainFunc
set "source=%~1"
shift /1
:mainFuncLoop
set args=%args%%1
if "%~2" neq "" shift /1&goto:mainFuncLoop
if defined args set "args=%args:~0,-1%"
echo(:mainFunc of %~nx0 source=%source% with args="%args%" is called from '%caller%'/%callType%
exit /b
scriptCaller.bat:
@echo off
set caller=empty
echo(%~0: call detectCallerScript hi there
call detectCallerScript hi there
echo(Back to %~0
echo(
call:someFunc
exit /b
:someFunc
set caller=empty
echo(%~n0 %~0: call detectCallerScript hi there
call detectCallerScript hi there
echo(Back to %~0
echo(
Output:
scriptCaller.bat: call detectCallerScript hi there
:mainFunc of detectCallerScript.bat source=scriptCaller.bat with args="hi there" is called from '{path}\scriptCaller.bat'/batch
Back to scriptCaller.bat
scriptCaller :someFunc: call detectCallerScript hi there
:mainFunc of detectCallerScript.bat source=:someFunc with args="hi there" is called from '{path}\scriptCaller.bat'/batch
Back to :someFunc
来源:https://stackoverflow.com/questions/43089515/how-to-get-the-name-of-calling-bat-script