Firstly, I saw this topic but I couldn't understand that.
Question :
There is a batch file in D:\path\to\file.bat
with following content :
echo %cd%
pause
Output is :
C:\
It must be D:\path\to
What am I doing wrong?
System read-only variable %CD%
keeps the path of the caller of the batch, not the batch file location.
You can get the name of the batch script itself as typed by the user with %0
(e.g. scripts\mybatch.bat
). Parameter extensions can be applied to this so %~dp0
will return the Drive and Path to the batch script (e.g. W:\scripts\
) and %~f0
will return the full pathname (e.g. W:\scripts\mybatch.cmd
).
You can refer to other files in the same folder as the batch script by using this syntax:
CALL %0\..\SecondBatch.cmd
This can even be used in a subroutine, Echo %0
will give the call label but, echo "%~nx0"
will give you the filename of the batch script.
When the %0
variable is expanded, the result is enclosed in quotation marks.
Very simple:
setlocal
cd /d %~dp0
File.exe
cd /d %~dp0
as first line of batch file and worked
"%~dp0"
rather than %~dp0
. Quotes will guarantee the path is taken as one token, even if there are spaces, and also protects against poison characters like &
.
Within your .bat file:
set mypath=%cd%
You can now use the variable %mypath%
to reference the file path to the .bat
file. To verify the path is correct:
@echo %mypath%
For example, a file called DIR.bat
with the following contents
set mypath=%cd%
@echo %mypath%
Pause
run from the directory g:\test\bat
will echo that path in the DOS command window.
%cd%
. No need to copy it first.
Here's what I use at the top of all my batch files. I just copy/paste from my template folder.
@echo off
:: --HAS ENDING BACKSLASH
set batdir=%~dp0
:: --MISSING ENDING BACKSLASH
:: set batdir=%CD%
pushd "%batdir%"
Setting current batch file's path to %batdir% allows you to call it in subsequent stmts in current batch file, regardless of where this batch file changes to. Using PUSHD allows you to use POPD to quickly set this batch file's path to original %batdir%. Remember, if using %batdir%ExtraDir or %batdir%\ExtraDir (depending on which version used above, ending backslash or not) you will need to enclose the entire string in double quotes if path has spaces (i.e. "%batdir%ExtraDir"). You can always use PUSHD %~dp0. [https: // ss64.com/ nt/ syntax-args .html] has more on (%~) parameters.
Note that using (::) at beginning of a line makes it a comment line. More importantly, using :: allows you to include redirectors, pipes, special chars (i.e. < > | etc) in that comment.
:: ORIG STMT WAS: dir *.* | find /v "1917" > outfile.txt
Of course, Powershell does this and lots more.
set batdir=%CD%
). It is not okay, because it is the path to the caller, not the bat file itself. The only valid way to get the path to the executing bat file is %~dp0
.
Success story sharing
stm.sql
inD:\Dir1\Dir2\stm.sql
. I needmysql.exe -u root -p mysql < %cd%\stm.sql
to execute that stm.sql commands.*.bat
or*.sh
?D:\Dir1\Dir2\batchfile.bat
andD:\Dir1\Dir2\stm.sql
. batchfile.bat content is :mysql.exe -u root -p mysql < D:\Dir1\Dir2\stm.sql
and stm.sql content is some MySQL commands.echo %~dp0
will return path to batch location.echo %~f0
will return path to the batch with filename.