为什么在提示符下输入相同的字符串而不是将其作为变量传递时得到不同的输出?

时间:2019-03-08 18:57:37

标签: powershell

有人可以向我解释为什么我输入相同的字符串时会看到不同的输出,一个是在powershell提示下输入,另一个是在传递变量时输入。我想知道在提示符下输入字符串时如何设置其格式,以产生与将变量作为变量传递时得到的输出相同的输出。

test.ps1

param (
    [Parameter(Mandatory=$true)]
    [String]
    $NewArgumentString
)

$NewArguments = (Write-Output $NewArgumentString | ConvertFrom-StringData)
$NewArguments

运行:

PS> $testString = "HOSTNAME = jburns-test`nIP = 127.0.0.1"
PS> .\test.ps1 -NewArgumentString $testString

Name                           Value
----                           -----
HOSTNAME                       jburns-test
IP                             127.0.0.1


PS> .\test.ps1

cmdlet a.ps1 at command pipeline position 1
Supply values for the following parameters:
NewArgumentString: HOSTNAME = jburns-test`nIP = 127.0.0.1

Name                           Value
----                           -----
HOSTNAME                       jburns-test`nIP = 127.0.0.1

enter image description here

1 个答案:

答案 0 :(得分:1)

此代码对提示变量与传入变量的响应不同的原因是,我们正在处理解释的字符串与 literal 字符串之间的差异。又称为单引号与双引号。

提示符处的字符串被视为文字字符串,而不是解释字符串。这就是为什么提示时您不能引用变量的原因。为了演示该示例的不同效果,让我们进行遍历,在该示例中,我们将传递的变量中的双引号替换为双引号,以模拟在提示符下以字符串形式编写:

PS> $testString = "HOSTNAME = jburns-test`nIP = 127.0.0.1"
PS> $testString2 = 'HOSTNAME = jburns-test`nIP = 127.0.0.1'

PS> .\test.ps1 -NewArgumentString $testString

Name                           Value
----                           -----
HOSTNAME                       jburns-test
IP                             127.0.0.1


PS> .\test.ps1 -NewArgumentString $testString2

Name                           Value
----                           -----
HOSTNAME                       jburns-test`nIP = 127.0.0.1

在这里,我们看到确认单引号字符串被解释为与提示符相同的确认。 真正发生的情况是两个字符串不同。对于第一个双引号字符串,赋值后,PowerShell会将两个字符组合“`n”(0x96 + 0x6E)转换为单个换行符“ LF”(0x0A)字符。我们可以通过比较字符串长度来看到这一点:

PS> $testString = "HOSTNAME = jburns-test`nIP = 127.0.0.1"
PS> $testString.Length
37

PS> $testString2 = 'HOSTNAME = jburns-test`nIP = 127.0.0.1'
PS> $testString2.Length
38

要真实地复制示例中的理论结果,让我们进入提示,将-n-“按位”字符串存储在变量中,方法是将n替换为不可打印的LF字符(只能通过使用ALT + numpad方法)ALT + 0010

PS> .\test.ps1

cmdlet a.ps1 at command pipeline position 1
Supply values for the following parameters:
NewArgumentString: HOSTNAME = jburns-test
IP = 127.0.0.1

Name                           Value
----                           -----
HOSTNAME                       jburns-test
IP                             127.0.0.1

瞧!我们已经复制了结果。 PowerShell尚未损坏。我们对函数和参数传递的信念得以恢复!


顺便说一句,可能不建议将字符串传递到函数中并依靠函数将其转换为哈希表,因为正如您所演示的那样,这可能会带来不可预测的结果。相反,我直接将Hash Table(类型[hashtable])传递给函数:

testHashTable.ps1

param (
    [Parameter(Mandatory=$true)]
    [hashtable]
    $MyHashTable
)

Write-Output $MyHashTable
PS> $testHashTable = @{ "HOSTNAME" = "jburns-test" ; "IP" = "127.0.0.1" }
PS> .\test.ps1 -MyHashTable $testHashTable

Name                           Value
----                           -----
IP                             127.0.0.1
HOSTNAME                       jburns-test