Powershell - 转义字符串传递给子进程 [英] Powershell - escaping string passed to child process

查看:51
本文介绍了Powershell - 转义字符串传递给子进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I spent some time figuring out the correct syntax for a Powershell script. However in the end it was trial and error approach and I would like to know why the syntax below doesn't work.

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

The script starts new Powershel in elevated mode and sets environment variable. Here's the excerpt:

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

如果我只是打印出变量 $arguments,它是一个我期望的数组:

If I just print out the variable $arguments, it's an array as I would expect:

-NoExit
-command
&{ [Environment]::SetEnvironmentVariable("MyVar1", "NewValue", [EnvironmentVariableTarget]::Machine) }

但是,在子 Powershell 中,双引号以某种方式被吃掉并丢失了.为什么?这是预期的行为吗?它输出:

However, in the child Powershell the double quotes are eaten somehow and missing. Why? Is it expected behavior? It outputs:

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 参数,该参数仅用于调试):

For reference, here's working version using single quotes instead of double quotes (I also removed -NoExit parameter, which was there only for debugging):

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

推荐答案

这是 PowerShell.exe 解析其命令行的方式.它主要遵循 .NET 命令行解析规则:

It is how PowerShell.exe parse its command line. It mostly follows .NET rules of command line parsing:

  • 空格是参数分隔符.PowerShell.exe 将通过单个空格连接各个参数,无论您使用多少个空格来分隔参数.

  • Space is an argument separator. PowerShell.exe will join individual arguments by single space regardless of how many spaces you use to separate arguments.

CMD> PowerShell -Command echo 'multiple   spaces'
multiple spaces

  • 如果你想在参数值中包含空格,那么你应该用双引号将空格括起来.双引号本身不是结果参数值的一部分,可以在参数内的任何位置:

  • If you want to include space in argument value, then you should enclose space in double quotes. Double quotes itself are not a part of resulting argument value and can be anywhere inside argument:

    CMD> PowerShell -Command echo 'mult"iple   spa"ces'
    multiple   spaces
    

  • 如果你想让文字双引号成为参数值的一部分,那么你必须用反斜杠将它转义:

  • If you want literal double quote to be part of argument value, then you have to escape it with backslash:

    CMD> PowerShell -Command echo 'literal\"double\"quotes'
    literal"double"quotes
    

  • 如果你想让文字反斜杠出现在双引号之前,那么你必须用另一个反斜杠来转义那个反斜杠.除此之外,反斜杠按字面解释,不需要转义:

  • If you want literal backslash to precede double quote, then you have to escape that backslash with another backslash. Other than that, backslash interpreted literally and does not need to be escaped:

    CMD> PowerShell -Command echo 'back\\slash\\"   something\\else\\"'
    back\\slash\   something\\else\
    

  • 这篇关于Powershell - 转义字符串传递给子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆