我正在学习如何使用批处理脚本中的参数,最后创建某种模板来读取参数和设置参数
@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
我非常感谢您提供的任何帮助。
答案 0 :(得分:4)
之所以这个
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存储在%1
中,丢失对当前批处理文件的引用。
在您的代码中,您将移动所有参数,直到所有参数都被处理完毕。这将最后一个参数保留在%0
内,此时事情变得有趣。
当请求%0
时,最后一个参数存储在%~dp0
内,并且当我们要求参数内引用的元素的驱动器和文件夹时,%0
尝试解析它假设你知道你要求什么,变量包含对文件系统中元素的有效引用,将其转换为绝对路径,然后检索所请求的元素。
在这里你遇到了两个案例
cmd
只包含一个没有斜杠或反斜杠的简单字符串。 %0
将其作为存储在当前活动目录中的文件名处理,因此,当您请求驱动器和路径时,将检索当前活动目录的驱动器和路径。在你的工作中#34; 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\"
包含带斜杠或反斜杠的字符串。同样的情况是,在BUT之前,字符串包含一个相对路径(第一个失败的情况),它以当前活动目录为前缀,或者是根文件夹的路径(第二个失败的情况),所以你以%0
你怎么解决?
最简单的解决方法可能是,如Magoo所提出的,在进行任何参数移位之前保存"C:\Users\user\script\what happens /here" -> %~dp0 = "C:\Users\user\script\what happens "
"C:/g" -> %~dp0 = "C:\"
参数的值。
另一种选择是将%0
命令更改为shift
,以表示转移将从第一个参数开始,保持shift /1
不变。
如果无法使用这些选项,您仍然可以从子程序中检索批处理文件的引用
%0
答案 1 :(得分:1)
我建议在%~d0
命令后SHIFT
可能不可靠,所以我在开始时保存其值。
也许This question可能有所帮助。我仍然首先保存~dp0
但是......