将空格作为parameter passing给bat文件

我有一个简单的蝙蝠脚本,从一个已知的目录复制文件到用户给出的目录。 我如何将path(可能包含空格)传递给我的脚本,并将其与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 ) 

如果我简单地调用脚本,我会得到以下错误:

 C:\Projects\Setup>install.cmd "C:\program files (x86)" ----------------- SETUP SCRIPT ----------------- files was unexpected at this time. C:\Projects\Setup> 

有趣的一个。 我喜欢收集关于在cmd /命令处理报价。

您的特定脚本通过使用%1而不是“%1”得到修复!

通过添加“回声”(或摆脱回声),你可以很容易地发现。

使用"%~1" 。 仅仅%~1就会消除周围的引号。 但是由于您无法知道input参数%1是否有引号,因此您应该确保通过"%~1"确认它们已被添加。 这在连接variables时特别有用,例如convert.exe "%~1.input" "%~1.output"

参考文献:

  • 使用批处理参数 (Microsoft链接)
  • 如何将parameter passing给batch file?

我认为OP的问题是他想要做以下件事:

  • 传递一个可能包含空格的参数
  • testing参数是否丢失

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

为了testing参数是否丢失,我总是学到的方法是:

 if "%1" == "" 

但是,如果实际参数被引用(因为它必须是如果该值包含空格),则会变成

 if ""actual parameter value"" == "" 

这会导致“意外”错误。 如果你改用

 if %1 == "" 

那么报价值不再出现错误。 但是在这种情况下,当价值缺失时,testing就不再起作用

 if == "" 

为了解决这个问题,在testing中使用任何其他的字符(除了有特殊意义的东西),而不是引号:

 if [%1] == [] if .%1. == .. if abc%1xyz == abcxyz 

如果你有一个空格的path,你必须用引号(“)来包围它。

不知道这是否正是你问的?

“%〜1”将在大多数时间工作。 但是有几件事情需要注意:

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

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

 REM example.cmd ECHO %~1 

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

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

 REM example2.cmd SETLOCAL EnableExtensions EnableDelayedExpansion SET "arg1=%~1" ECHO "%~1" ECHO !arg1:"=! 

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

所以,没有办法使parsing参数安全。

(编辑: EnableDelayedExpansion无法在Windows NT 4中工作。感谢这里的信息: http : //www.robvanderwoude.com/local.php )

 @echo off setlocal enableextensions enabledelayedexpansion 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 @echo !PWA_PATH! vs. %1 goto end ) :READ_WSS_SERVER_EXTENSIONS_PATH echo ok goto end :CANCEL echo cancelled :end echo. final %PWA_PATH% vs. %1 

正如VardhanDotNet提到的, %1就足够了。

"%1%"会在引号周围添加引号: ""c:\Program Files\xxx""这意味着:

  • '空string'( "" ),
  • 其次是'c:\ Program',
  • 其次是“意想不到的”“文件\ xxx”,
  • 后跟一个空string( ""

但是请注意,如果您需要在IF子句中使用PWA_PATH ,则需要将其作为!PWA_PATH! (因此enabledelayedexpansion作为脚本的开始)

如果您的path包含空格,请尝试使用%~s1 。 这将删除空间并附加~1到您的path,更重要的是它指的是文件的绝对path。 尝试使用它。