The Windows Command Processor cmd.exe
processes a batch file line by line. This means it opens a batch file, reads the next line, parses it, and if there is no more line to read, it closes the batch file. Then it executes the command(s) on the parsed line. See How does the Windows Command Interpreter (CMD.EXE) parse scripts?
The Windows command processor exits the processing of a batch file if there is a serious syntax here. This error condition handling is used here.
Create a batch file with following lines:
@echo off
goto
echo Third line!
Open a command prompt and run this batch file by typing its full qualified file name, i.e. drive + path + name + extension enclose in double quotes.
There is the following error message output by cmd.exe
because of batch label is missing on second line.
No batch label specified to GOTO command.
The third line is not executed anymore by cmd.exe
because of batch file processing is exited after execution of second command line because of this serious syntax error on which it is unclear for cmd.exe
where to continue the batch file processing.
Now let us look on the command line:
goto 2>nul & del /Q "%APP_PATH%"
This is a command line with two commands on one line as described in detail by my answer on Single line with multiple commands using Windows batch file.
The first command goto
with the missing batch label results in exiting the batch file processing. The error message output by cmd.exe
in this case is redirected with 2>nul
to device NUL to suppress it. But the second command del /Q "%APP_PATH%"
with the already expanded environment variable %APP_PATH%
is already in the commands queue. For that reason this command is executed next.
Then cmd.exe
does not even try to open the batch file once more to read the third line as the invalid goto
command results in exiting batch file processing which in this case does not even exist anymore if %APP_PATH%
references the name of the batch file.
BTW: APP_PATH
is a strange because of misleading environment variable name for a file name with full path.
Here is an even better example:
Create first a batch file with name Test1.cmd
with following lines:
@echo off
echo %~nx0 is calling Test2.cmd.
call "%~dp0Test2.cmd"
echo %~nx0 is processed further.
Create second a batch file with name Test2.cmd
with following lines:
@echo off
set "BatchFile=%~f0"
echo %~nx0 is deleting itself now.
goto 2>nul & del /A /F "%BatchFile%"
Then run from within a command prompt window Test1.cmd
. The output is:
Test1.cmd is calling Test2.cmd.
Test2.cmd is deleting itself now.
Test1.cmd is processed further.
It can be seen that Test2.cmd
deleted itself without showing any error message by cmd.exe
processing Test2.cmd
. But processing of Test1.cmd
is continued after Test2.cmd
deleted itself.
The option /Q
is not really necessary on deleting a single file and the file definitely exists on running the command. The option /A
is useful to delete the batch file even if it has the hidden attribute set as otherwise del
would not delete it. The option /F
is useful to delete the batch file even if the read-only attribute is set.
Another command method is using as last command line in a batch file which should delete itself the command line:
del /A /F "%~f0" & exit
But it has a disadvantage as it can be seen on creating a Test2.cmd
with the lines:
@echo off
echo %~nx0 is deleting itself now.
del /A /F "%~f0" & exit
Run Test1.cmd
from within the command prompt window. The batch file Test2.cmd
deletes itself, but command exit
results in exiting the cmd.exe
opened with opening the command prompt window and processing both batch files. For that reason Test1.cmd
is not further processed and the console window is closed immediately.
Appending the option /B
after command exit
would result in not exiting cmd.exe
, but two error messages would be output by cmd.exe
because of not finding anymore Test2.cmd
.
For that reason the usage of goto 2>nul & del /A /F "%~f0"
is a best practice example for self-deletion of a batch file.
BTW: The order or the two commands matters. The usage of del /A /F "%~f0" & goto 2>nul
would result in an error message output by cmd.exe
as in this case it tries to open the already deleted batch file once more.