繁体   English   中英

从powershell.exe向脚本传递参数

[英]passing parameters to script from powershell.exe

我有一个像这样的脚本:

param(
[string]$root,
[string]$bin,
[string]$out,
[string]$zdir
)


echo "args..."
echo "Root: $root", "zdir: $zdir", "out: $out", "bin: $bin"

我按如下方式调用它:

powershell.exe -nologo -noprofile -file "C:\Users\arun_jayapal\Documents\Visual Studio 2013\Projects\OutlookCompass\OutlookCompass\zip.ps1" -root "C:\Users\arun_jayapal\Documents\Visual Studio 2013\Projects\OutlookCompass\OutlookCompass\" -zdir "Zip" -out "output.zip" -bin "C:\Users\arun_jayapal\Documents\Visual Studio 2013\Projects\OutlookCompass\OutlookCompass\bin\Debug\" 

但是我的输出恰恰相反:

C:\code\misc>powershell.exe -nologo -noprofile -file "C:\Users\arun_jayapal\Docu
ments\Visual Studio 2013\Projects\OutlookCompass\OutlookCompass\zip.ps1" -root "
C:\Users\arun_jayapal\Documents\Visual Studio 2013\Projects\OutlookCompass\Outlo
okCompass\" -zdir "Zip" -out "output.zip" -bin "C:\Users\arun_jayapal\Documents\
Visual Studio 2013\Projects\OutlookCompass\OutlookCompass\bin\Debug\"
args...
Root: C:\Users\arun_jayapal\Documents\Visual Studio 2013\Projects\OutlookCompas
s\OutlookCompass" -zdir Zip -out output.zip -bin C:\Users\arun_jayapal\Document
s\Visual
zdir:
out: 2013\Projects\OutlookCompass\OutlookCompass\bin\Debug"
bin: Studio

您的问题是您正在从cmd.exe调用powershell脚本,并且对于许多旧版.exe程序,序列\\"用于将引号转义为参数。Powershell遵守此约定,因此在调用Powershell.exe时必须请遵循此转义约定。

所以:

-root "something\" -zdir "Zip" -out "output.zip" -bin "something\"

是包含两个双引号一个参数逃脱与琴弦\\"cmd删除其他双引号,所以Zipoutput.zip是引号外的字符串,但它们不包含任何空格他们不拆论点。

这应该工作:

-root "something\\" -zdir "Zip" -out "output.zip" -bin "something\\"

在引号之前加倍反斜杠意味着将传递单个反斜杠,并且引号失去其特殊含义。 不要将任何其他反斜杠加倍,因为当一个或多个反斜杠序列中的一个或多个使用双引号引起来时, cmd仅将反斜杠视为特殊反斜杠。

或者,也可以省略尾随反斜杠,并在脚本中需要的地方插入它们。

或者只是将powershell本身用作主命令提示符,然后完全放弃cmd

顺便说一句,如果您从内部调用powershell的另一个副本,则会将其识别为特殊内容,并且参数在base64中编码并通过-EncodedCommand命令行选项传递,因此在这种情况下,无需担心转义的引号。

Duncan的有用答案包括关键指针(以及有用的背景信息): \\"在参数值的末尾被解释为转义的 " ,这会导致参数边界被误解

您的选择是:

  • 如Duncan建议的那样,在每个参数值的末尾使用\\\\"代替\\" (例如"c:\\foo bar\\\\"
  • 完全省略路径中的尾随\\ (例如, "c:\\foo bar"而不是"c:\\foo bar\\"
  • 如果要避免修改参数值 ,请使用以下单引号解决方案(已在v3上验证)。

单引号解决方案:

假设您是从cmd.exe调用此文件,无论是从批处理文件还是在命令提示符下调用(在PowerShell中,您都可以使用& <script> ...

  • 使用引号而不是双引号
  • 使用-Command参数,而不是-File
  • 在脚本路径前添加& (以^ cmd.exe ,以使cmd.exe将其视为文字)
powershell.exe -noprofile -command ^& 'C:\Users\arun_jayapal\Documents\Visual Studio 2013\Projects\OutlookCompass\OutlookCompass\zip.ps1' -root 'C:\Users\arun_jayapal\Documents\Visual Studio 2013\Projects\OutlookCompass\OutlookCompass\' -zdir 'Zip' -out 'output.zip' -bin 'C:\Users\arun_jayapal\Documents\Visual Studio 2013\Projects\OutlookCompass\OutlookCompass\bin\Debug\'
  • 之所以-Command ,是因为通过使用-Command (和PowerShell的& (调用)运算符来调用其路径具有嵌入式空格的脚本),命令行的其余部分可以用PowerShell样式加单引号引起来,而不必使用单引号引起来。解释(甚至不使用PowerShell自身的启动命令行解析所基于的C样式参数解析,但嵌入式" chars除外。-参见下文)。

  • 需要使用此方法转义的唯一字符是:

    • 使用''将文字'嵌入参数中。
    • 使用\\"在参数中嵌入文字"
    • 如果您需要转义%字符。 为了防止它们被cmd.exe解释为环境变量引用的一部分(无论使用单引号还是双引号的字符串,都必须这样做),请参阅我的答案
  • 请注意,要在当前目录中执行脚本,必须像在PowerShell中一样对脚本文件名加.\\前缀。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM