【问题标题】:Powershell - escaping string passed to child processPowershell - 转义字符串传递给子进程
【发布时间】:2017-05-18 03:02:49
【问题描述】:

我花了一些时间找出 Powershell 脚本的正确语法。但是最后它是反复试验的方法,我想知道为什么下面的语法不起作用。

脚本以提升模式启动新的 Powershel 并设置环境变量。摘录如下:

$x = "NewValue"
$arguments = "-NoExit", "-command", "&{ [Environment]::SetEnvironmentVariable(`"MyVar1`", `"$x`", [EnvironmentVariableTarget]::Machine) }"
Start-Process powershell -Verb runAs -ArgumentList $arguments

如果我只是打印出变量$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 参数,该参数仅用于调试):

$x = "NewValue"
$arguments = "-command", "&{ [Environment]::SetEnvironmentVariable('MyVar1', `'$x`', [EnvironmentVariableTarget]::Machine) }"
Start-Process powershell -Verb runAs -ArgumentList $arguments

【问题讨论】:

  • $arguments = "-NoExit", "-command", "`"&{ [Environment]::SetEnvironmentVariable(\`"MyVar1\`", \`"$x\`", [EnvironmentVariableTarget]::Machine) }`""
  • @PetSerAl 你为什么要回答?作为 cmets,这很令人困惑。
  • @JPBlanc 恕我直言,它需要不仅仅是一个代码 sn-p 才能成为正确的答案。
  • 您可以将您的代码作为答案,稍后再编辑您的答案。

标签: powershell


【解决方案1】:

这就是PowerShell.exe 解析其命令行的方式。它主要遵循.NET rules of command line parsing

  • 空格是一个参数分隔符。 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\
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-01
    • 2014-09-04
    • 2019-07-19
    • 2018-11-14
    • 2016-12-29
    • 1970-01-01
    • 2022-12-20
    相关资源
    最近更新 更多