最后一个参数中的正斜杠导致改变批处理文件(“%〜dp0”)的目录的路径 [英] Forward slash in last argument causes path to directory of batch file ("%~dp0") to change

查看:1848
本文介绍了最后一个参数中的正斜杠导致改变批处理文件(“%〜dp0”)的目录的路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习一个如何使用批处理脚本中的参数,最后创建一些用于读取参数和设置参数的模板。

I am learning a bit how to work with parameters in a batch-script and ended up creating some kind of template for reading arguments and setting parameters

@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 )创建一个函数, c $ c> arg_default ):

The first echo that prints the directory is important for my question (see later) After that I create a function for each flag (arg_/flag) and one for arguments without a flag (the 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 $ c> C:\Users\user\scripts\params.bat 并将目录放在我可以执行脚本的路径中:

When I put everything in a batch-file, let's say C:\Users\user\scripts\params.bat and put the directory in the path I can execute the script:

> 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

in函数允许我以任何顺序输入参数,但如果我把G标志作为最后我得到这个奇怪的行为:

The fact I put it in functions allows me to enter the parameters in whatever order I wish but if I put the G-flag as last I get this strange behaviour:

> 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 就会像这个例子中那样奇怪:

The %~dp0 returns only C:\! I tried it with other parameters, moved the batch-file to another directory, called it within the directory, the %~dp0 kept returning only C:\. In fact each time the last argument contains a "/" the %~dp0 will behave "strangely" like in this example:

> 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

Can someone please explain me why this is happening? I cannot figure out why and could not find anything on the web either. I use Windows 10

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

I really appreciate any help you can provide.

推荐答案

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

不工作是...在这两种情况下它不工作!

doesn't work is ... that in both cases it does not work!

,你的问题是 shift 命令。默认情况下,它会移动所有参数,因此第十个参数存储在%9 ,旧的%9 存储在中存储%8 ...和%1 >%0 ,失去对当前批处理文件的引用。

As Magoo points, your problem is the shift command. By default it shifts all the arguments, so the tenth argument is stored in %9, the old %9 is stored in %8 ... and %1 is stored in %0, losing the reference to the current batch file.

在您的代码中,您将移动所有参数,直到所有参数都被处理。这留下了%0 中的最后一个参数,并且在这一刻,事情变得有趣。

In your code you are shifting all the arguments until all are processed. This leaves the last argument inside %0, and at this moment things become interesting.

%〜dp0 ,最后一个参数存储在%0 中,因为我们要求引用元素的驱动器和文件夹在参数中, cmd 尝试解决它,假设你知道你要求什么,该变量包含对文件系统中的元素的有效引用,将其转换为绝对路径然后检索请求的元素。

When %~dp0 is requested, the last argument is stored inside %0 and, as we ask for the drive and folder of the element referenced inside the argument, cmd tries to resolve it assumming you know what you ask for and the variable contains a valid reference to a element in the file system, converts it to a absolute path and then retrieve the requested elements.

在这里您遇到了两种情况

And here you have faced two cases


  • %0 只包含一个不带斜线或反斜杠的简单字符串。 cmd 将其作为存储在当前活动目录中的文件名处理,因此,在请求驱动器和路径时,将检索当前活动目录的驱动器和路径。在您的工作情况下,您以
  • 结束
  • %0 contains just a simple string without slashes or backslashes. cmd handles it as a file name that is stored in the current active directory, so, as you request a drive and path, the drive and path of the current active directory are retrieved. In your "working" cases you end with
"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 包含带斜杠或反斜杠的字符串。这是相同的情况下,在字符串包含相对路径(第一个失败的情况)前面的当前活动目录或从根文件夹的路径(第二个失败的情况)之前,因此结束

    • %0 contains a string with slashes or backslashes. It is the same case that before BUT the string contains a relative path (first failing case) that is prefixed with the current active directory or with a path from the root folder (second failing case) so you end with
    • "C:\Users\user\script\what happens /here" -> %~dp0 = "C:\Users\user\script\what happens "
      "C:/g" -> %~dp0 = "C:\"
      

      如何解决?

      根据Magoo的建议,最简单的解决方法是在执行任何转换之前保存%0 参数的值

      The easiest way to solve it could be, as proposed by Magoo, to save the value of the %0 argument before doing any shifting of the arguments.

      另一个选择是将 shift 命令更改为 shift / 1 ,表示转换将从第一个参数开始,%0 不变。

      Another option is to change shift commands into shift /1, to signal that the shifting will start at the first argument, leaving %0 unchanged.

      如果没有这个选项可以使用,你仍然可以从子程序内检索批处理文件的引用

      If none of this options can be used you can still retrieve a reference to the batch file from inside a subroutine

      @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
      

      这篇关于最后一个参数中的正斜杠导致改变批处理文件(“%〜dp0”)的目录的路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆