将空格作为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”将在大多数时间工作。 但是有几件事情需要注意:
- 它在Windows NT 4.0中不受支持。 您需要Windows 2000或更高版本。 (如果您正在编写与旧操作系统兼容的脚本,请注意。)
- 它不会使参数安全和消毒。 我的观察是, 没有办法正确清理 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。 尝试使用它。