将带空格的路径作为bat文件的参数传递

kjv*_*kjv 58 parameters command batch-file

我有一个简单的bat脚本,它将文件从已知目录复制到用户指定的目录.如何将路径(可能包含空格)传递给我的脚本并将其与xcopy命令一起使用?


在我的代码中,我有以下内容

:READ_PWA_PATH
    if "%1" == "" ( 
        rem Set default path
        set PWA_PATH="C:\Program Files\PWA"
        rem
        echo You have not specified your PWA url.
        echo Default will be assumed: C:\Program Files\PWA. 
        choice /C:YN /M:"Do you wish to continue [Y] or cancel the script [N]?"
            IF ERRORLEVEL ==2 GOTO CANCEL
            IF ERRORLEVEL ==1 GOTO READ_WSS_SERVER_EXTENSIONS_PATH
        GOTO END
    ) else (
        set PWA_PATH=%1
    )
Run Code Online (Sandbox Code Playgroud)

如果我只是调用脚本,我会收到以下错误:

C:\Projects\Setup>install.cmd "C:\program files (x86)"

-----------------
SETUP SCRIPT
-----------------

files was unexpected at this time.
C:\Projects\Setup>
Run Code Online (Sandbox Code Playgroud)

小智 107

使用"%~1".%~1单独删除周围的引号.但是,由于您无法知道输入参数是否%1有引号,因此您应该确保"%~1"添加它们.这在连接变量时特别有用,例如convert.exe "%~1.input" "%~1.output"


vrd*_*dhn 21

有趣的一个.我喜欢在cmd/command中收集有关引号处理的引号.

使用%1而不是"%1"来修复您的特定脚本!

通过添加'echo on'(或摆脱回声),你可以很容易地找到它.

  • 尽管此答案被问题所有者标记为最佳,但它解决了一个问题,并添加了其他问题。如果您只是从 %1 中删除引号,则在未提供引号时(或根本不提供任何参数),您的代码可能会出现错误。最安全的解决方案是使用 %~1,如@zikaS 的回答所述。 (9认同)
  • 如何用 %* 转义所有参数? (2认同)

小智 14

我认为业务方案的问题是,他想要做BOTH如下:

  • 传递可能包含空格的参数
  • 测试参数是否缺失

正如几个海报所提到的,要传递包含空格的参数,必须用双引号括住实际参数值.

为了测试参数是否缺失,我总是学到的方法是:

if "%1" == ""
Run Code Online (Sandbox Code Playgroud)

但是,如果引用实际参数(如果值包含空格必须是这样),则变为

if ""actual parameter value"" == ""
Run Code Online (Sandbox Code Playgroud)

这会导致"意外"错误.如果你改用

if %1 == ""
Run Code Online (Sandbox Code Playgroud)

那么引用值不再出现错误.但是在这种情况下,当值缺失时,测试不再有效 - 它就变成了

if  == ""
Run Code Online (Sandbox Code Playgroud)

要解决此问题,请使用任何其他字符(对DOS具有特殊含义的字符除外)而不是测试中的引号:

if [%1] == []
if .%1. == ..
if abc%1xyz == abcxyz
Run Code Online (Sandbox Code Playgroud)

  • 或者,使用**"%〜1"**将删除外部引用并允许进行真正的测试,因为您永远不知道用户将键入什么,例如****或**"this"**. (7认同)

Exp*_*r09 7

"%~1"大部分时间都可以使用.但是,您需要注意以下几点:

  1. 它在Windows NT 4.0中不受支持.您需要Windows 2000或更高版本.(如果您要编写与旧操作系统兼容的脚本,请注意.)
  2. 它不会使参数安全和消毒.我的观察是,无法正确清理 CMD脚本中的命令行参数.

为了证明第二点,让我举一个例子:

REM example.cmd
ECHO %~1
Run Code Online (Sandbox Code Playgroud)

运行example.cmd dummy^&DIR.&符号在此处转义(^&)以防止shell作为命令分隔符进行解释,从而使其成为传递给脚本的参数的一部分.DIR被解释为运行脚本的子shell内的命令,它不应该在那里.

引用它可能会有一段时间,但仍然不安全:

REM example2.cmd
SETLOCAL EnableExtensions EnableDelayedExpansion
SET "arg1=%~1"
ECHO "%~1"
ECHO !arg1:"=!
Run Code Online (Sandbox Code Playgroud)

example2.cmd foo^"^&DIR^&^"bar会打破它.DIR命令将运行两次,一次在SET之后,另一次在第一次ECHO之后.你看到"%~1"你认为被引用得很好的参数本身没有引用.

因此,无法使解析参数安全.

(编辑:EnableDelayedExpansion在Windows NT 4中也不起作用.感谢此处的信息:http://www.robvanderwoude.com/local.php)


小智 5

如果您有一个带空格的路径,则必须用引号(")括起来.

不确定这是不是你要问的那个?