繁体   English   中英

最后一个参数中的正斜杠导致更改批处理文件目录(“%〜dp0”)的路径

[英]Forward slash in last argument causes path to directory of batch file (“%~dp0”) to change

我正在学习一些如何在批处理脚本中使用参数的方法,并最终创建了某种用于读取参数和设置参数的模板

@echo off
SetLocal EnableDelayedExpansion
set needextra=
set errstat=
set noflag=
set param_f=Not set yet
set param_g=You didn't use G-flag

:readARGS
IF [%1] == [] goto :endARGS
call :arg_%1 2> nul
IF ERRORLEVEL 1 call :arg_default %1
SHIFT
IF DEFINED needextra (
    set %needextra%=%~1
    SHIFT
    set needextra=
)
goto :readARGS
:endARGS
echo path to directory of batch script: %~dp0
echo    - noflag:  !noflag!
echo    - param_f: !param_f!
echo    - param_g: !param_g!
EndLocal
exit /b 0

打印目录的第一个回显对于我的问题很重要(请参阅下文)。此后,我为每个标志( arg_/flag )创建一个函数,为没有标志的参数创建一个函数( arg_default ):

:arg_/f           -- flag f: set param_f to value of next argument
set needextra=param_f
exit /b 0

:arg_/g           -- flag g: just set the param_g to a value
set param_g=You used the G-flag
exit /b 0

:arg_default      -- default, neither flag f or g: just set the noflag
echo noflag=%~1
exit /b 0

当我将所有内容放入批处理文件中时,假设C:\\Users\\user\\scripts\\params.bat并将目录放在可以执行脚本的路径中:

> params "just an arg"
path to directory of batch script: C:\Users\user\scritpts\
   - noflag:  just an arg
   - param_f: Not set yet
   - param_g: You didn't use G-flag
> params another /G /F "this is f"
path to directory of batch script: C:\Users\user\scritpts\
   - noflag:  another
   - param_f: this is f
   - param_g: You used the G-flag

我把它放在函数中的事实使我可以按希望的顺序输入参数,但是如果我将G-flag放在最后,则会出现这种奇怪的行为:

> params /F "this is f again" bizar /G
path to directory of batch script: C:\
   - noflag:  bizar
   - param_f: this is f again
   - param_g: You used the G-flag

%~dp0仅返回C:\\ 我尝试了其他参数,将批处理文件移动到另一个目录中,在目录中称为%~dp0仅返回C:\\ 实际上,每次最后一个参数包含“ /”时, %~dp0行为都会像下面的示例一样“奇怪”:

> params /G /F stranger "what happens /here"
path to directory of batch script: C:\Users\user\script\what happens \
   - noflag:  what happens /here
   - param_f: stranger
   - param_g: You used the G-flag

有人可以解释一下为什么会这样吗? 我不知道为什么,也无法在网上找到任何东西。 我使用Windows 10

我非常感谢您可以提供的任何帮助。

之所以这样

params "just an arg"
params another /G /F "this is f"

工程和这个

params /G /F stranger "what happens /here"
params /F "this is f again" bizar /G

不起作用的是...在两种情况下都不起作用!

正如Magoo所指出的,您的问题是shift命令。 默认情况下,它会移动所有参数,因此第十个参数存储在%9 ,旧的%9存储在%8 ...中, %1存储在%0 ,从而丢失了对当前批处理文件的引用。

在代码中,您将转移所有参数,直到处理完所有参数为止。 这将最后一个参数留在%0 ,这时事情变得很有趣。

当请求%~dp0 ,最后一个参数存储在%0内部,并且当我们要求在参数内部引用的元素的驱动器和文件夹时, cmd尝试解析它,假设您知道您要的内容并且变量包含一个对文件系统中元素的有效引用,将其转换为绝对路径,然后检索请求的元素。

在这里您遇到了两种情况

  • %0仅包含一个不带斜杠或反斜杠的简单字符串。 cmd其作为存储在当前活动目录中的文件名进行处理,因此,当您请求驱动器和路径时,将检索当前活动目录的驱动器和路径。 在您的“工作”情况下,您以
"C:\Users\user\script\just an arg" -> %~dp0 = "C:\Users\user\script\"
"C:\Users\user\script\this is f"   -> %~dp0 = "C:\Users\user\script\"
  • %0包含带斜杠或反斜杠的字符串。 同样的情况是,在字符串出现之前,字符串包含相对路径(第一个失败的情况),该路径以当前活动目录或根文件夹的路径作为前缀(第二个失败的情况),因此您以
"C:\Users\user\script\what happens /here" -> %~dp0 = "C:\Users\user\script\what happens "
"C:/g" -> %~dp0 = "C:\"

你怎么解决呢?

如Magoo所建议的那样,最简单的解决方法是在对参数进行任何转换之前保存%0参数的值。

另一个选择是将shift命令更改为shift /1 ,以指示该移位将从第一个参数开始,而%0保持不变。

如果这些选项都不能使用,您仍然可以从子例程中检索对批处理文件的引用

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Ensure %0 is discarded    
    shift
    echo %0

    call :getCurrentBatchFolder dp0
    echo %dp0%

    exit /b

:getCurrentBatchFolder returnVar
    set "%~1=%~dp0"
    goto :eof

我建议在执行SHIFT命令后%~d0可能不可靠,因此我将在开始时保存其值。

也许这个问题可能有帮助。 我仍然会先保存~dp0 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM