命令行. cmd/. bat 脚本,如何获取正在运行的脚本的目录

如何获取运行的脚本的目录并在. cmd 文件中使用它?

117491 次浏览

Raymond Chen has a few ideas:

https://devblogs.microsoft.com/oldnewthing/20050128-00/?p=36573

Quoted here in full because MSDN archives tend to be somewhat unreliable:

The easy way is to use the %CD% pseudo-variable. It expands to the current working directory.

set OLDDIR=%CD%
.. do stuff ..
chdir /d %OLDDIR% &rem restore current directory

(Of course, directory save/restore could more easily have been done with pushd/popd, but that's not the point here.)

The %CD% trick is handy even from the command line. For example, I often find myself in a directory where there's a file that I want to operate on but... oh, I need to chdir to some other directory in order to perform that operation.

set _=%CD%\curfile.txt
cd ... some other directory ...
somecommand args %_% args

(I like to use %_% as my scratch environment variable.)

Type SET /? to see the other pseudo-variables provided by the command processor.

Also the comments in the article are well worth scanning for example this one (via the WayBack Machine, since comments are gone from older articles):

http://blogs.msdn.com/oldnewthing/archive/2005/01/28/362565.aspx#362741

This covers the use of %~dp0:

If you want to know where the batch file lives: %~dp0

%0 is the name of the batch file. ~dp gives you the drive and path of the specified argument.

This is equivalent to the path of the script:

%~dp0

This uses the batch parameter extension syntax. Parameter 0 is always the script itself.

If your script is stored at C:\example\script.bat, then %~dp0 evaluates to C:\example\.

ss64.com has more information about the parameter extension syntax. Here is the relevant excerpt:

You can get the value of any parameter using a % followed by it's numerical position on the command line.

[...]

When a parameter is used to supply a filename then the following extended syntax can be applied:

[...]

%~d1 Expand %1 to a Drive letter only - C:

[...]

%~p1 Expand %1 to a Path only e.g. \utils\ this includes a trailing \ which may be interpreted as an escape character by some commands.

[...]

The modifiers above can be combined:

%~dp1 Expand %1 to a drive letter and path only

[...]

You can get the pathname of the batch script itself with %0, parameter extensions can be applied to this so %~dp0 will return the Drive and Path to the batch script e.g. W:\scripts\

for /F "eol= delims=~" %%d in ('CD') do set curdir=%%d


pushd %curdir%

Source

This answer will also work if the batch file is invoked without an explicit path!

First the script determines if the batch file was called with a path. If that's the case that path is used. If not, the %path% is searched to find the batch file.

@echo off
setlocal enableextensions enabledelayedexpansion


for /f %%i in ('cd') do set CURDIR=%%i
set LAUNCHERPATH=%~dp0


if "%LAUNCHERPATH%" neq "%CURDIR%\" goto LAUNCHERPATHOK


set LIST=%PATH%


:ProcessList
for /f "tokens=1* delims=;" %%a in ("!LIST!") do (
if "%%a" neq "" (
set x=%%a
IF EXIST "%%a%0.bat" GOTO FOUND1
IF EXIST "%%a\%0.bat" GOTO FOUND0
IF EXIST "%%a%0" GOTO FOUND1
IF EXIST "%%a\%0" GOTO FOUND0
)
if "%%b" NEQ "" (
set List=%%b
goto :ProcessList
)
)
exit 1


:FOUND0
set x=%x%\
:FOUND1
set LAUNCHERPATH=%x%


:LAUNCHERPATHOK


echo %LAUNCHERPATH%

Kudos also to dos batch iterate through a delimited string for parsing the path variable