Powershell – 转义string传递给subprocess
我花了一些时间搞清楚Powershell脚本的正确语法。 但最后它是试错法,我想知道为什么下面的语法不起作用。
该脚本以提升模式启动新的Powershel并设置环境variables。 这是摘录:
$x = "NewValue" $arguments = "-NoExit", "-command", "&{ [Environment]::SetEnvironmentVariable(`"MyVar1`", `"$x`", [EnvironmentVariableTarget]::Machine) }" Start-Process powershell -Verb runAs -ArgumentList $arguments
如果我只是打印出variables$arguments
,这是一个数组,我所期望的:
-NoExit -command &{ [Environment]::SetEnvironmentVariable("MyVar1", "NewValue", [EnvironmentVariableTarget]::Machine) }
然而,在小孩Powershell双引号被吃掉了不知何故和失踪。 为什么? 这是预期的行为? 它输出:
At line:1 char:42 + &{ [Environment]::SetEnvironmentVariable(MyVar1, NewValue, [EnvironmentVariableT ... + ~ Missing ')' in method call. At line:1 char:42 + &{ [Environment]::SetEnvironmentVariable(MyVar1, NewValue, [EnvironmentVariableT ... + ~~~~~~ Unexpected token 'MyVar1' in expression or statement. At line:1 char:48 + &{ [Environment]::SetEnvironmentVariable(MyVar1, NewValue, [EnvironmentVariableT ... + ~ Missing argument in parameter list. At line:1 char:2 + &{ [Environment]::SetEnvironmentVariable(MyVar1, NewValue, [EnvironmentVariableT ... + ~ Missing closing '}' in statement block. At line:1 char:96 + ... arget]::Machine) } + ~ Unexpected token ')' in expression or statement. At line:1 char:98 + ... get]::Machine) } + ~ Unexpected token '}' in expression or statement. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
我的环境:
> $PSVersionTable Name Value ---- ----- PSVersion 4.0 WSManStackVersion 3.0 SerializationVersion 1.1.0.1 CLRVersion 4.0.30319.42000 BuildVersion 6.3.9600.17400 PSCompatibleVersions {1.0, 2.0, 3.0, 4.0} PSRemotingProtocolVersion 2.2
================================================== =============
作为参考,这里的工作版本使用单引号,而不是双引号(我也删除了-NoExit参数,这只是为了debugging):
$x = "NewValue" $arguments = "-command", "&{ [Environment]::SetEnvironmentVariable('MyVar1', `'$x`', [EnvironmentVariableTarget]::Machine) }" Start-Process powershell -Verb runAs -ArgumentList $arguments
PowerShell.exe
是如何parsing其命令行的。 它主要遵循命令行parsing的.NET规则 :
-
空间是一个论据分隔符。 无论您使用多less个空格来分隔参数,
PowerShell.exe
都会通过单个空间来连接各个参数。CMD> PowerShell -Command echo 'multiple spaces' multiple spaces
-
如果要在参数值中包含空格,则应该用双引号括起空格。 双引号本身不是结果参数值的一部分,可以是参数内的任何地方:
CMD> PowerShell -Command echo 'mult"iple spa"ces' multiple spaces
-
如果你希望字面双引号是参数值的一部分,那么你必须用反斜线来转义它:
CMD> PowerShell -Command echo 'literal\"double\"quotes' literal"double"quotes
-
如果你希望字面反斜杠在双引号之前,那么你必须用另一个反斜线来反斜线。 除此之外,反斜杠字面解释,不需要转义:
CMD> PowerShell -Command echo 'back\\slash\\" something\\else\\"' back\\slash\ something\\else\