Powershell 为什么在提示符中输入同一字符串与将其作为变量传递时会得到不同的输出?
有人能解释一下,当我输入相同的字符串时,为什么会看到不同的输出—一个是在powershell提示时输入的,另一个是在我传递变量时输入的。我想知道在提示符中输入字符串时,需要如何格式化字符串,以产生与作为变量传递字符串时相同的输出 测试.ps1Powershell 为什么在提示符中输入同一字符串与将其作为变量传递时会得到不同的输出?,powershell,Powershell,有人能解释一下,当我输入相同的字符串时,为什么会看到不同的输出—一个是在powershell提示时输入的,另一个是在我传递变量时输入的。我想知道在提示符中输入字符串时,需要如何格式化字符串,以产生与作为变量传递字符串时相同的输出 测试.ps1 param ( [Parameter(Mandatory=$true)] [String] $NewArgumentString ) $NewArguments = (Write-Output $NewArgumentString
param (
[Parameter(Mandatory=$true)]
[String]
$NewArgumentString
)
$NewArguments = (Write-Output $NewArgumentString | ConvertFrom-StringData)
$NewArguments
param (
[Parameter(Mandatory=$true)]
[hashtable]
$MyHashTable
)
Write-Output $MyHashTable
运行:
此代码对提示与传入变量的响应不同的原因是,我们处理的是解释字符串与文本字符串之间的差异。a、 k.a.单引号与双引号 提示处的字符串被视为文字字符串,而不是解释字符串。这就是为什么在提示时不能引用变量。为了演示该示例的不同效果,让我们运行一下,在传递的变量中将双引号替换为单引号,以模拟在提示时写入字符串:
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替换为不可打印的LF字符(只能使用该方法)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没有坏。我们对函数和参数传递的信心恢复了
另一方面,可能不建议将字符串传递到函数中并依赖函数将其转换为哈希表,因为正如您已经演示的那样,这可能会产生不可预测的结果。相反,我会直接将(键入
[hashtable]
)直接传递到函数中:
testHashTable.ps1
param (
[Parameter(Mandatory=$true)]
[String]
$NewArgumentString
)
$NewArguments = (Write-Output $NewArgumentString | ConvertFrom-StringData)
$NewArguments
param (
[Parameter(Mandatory=$true)]
[hashtable]
$MyHashTable
)
Write-Output $MyHashTable
我的理解是,除非您提供模板,否则每个
key=value
对必须位于自己的一行上。看起来转义新行并没有像这样扩展。这是真的,但在我的本地测试中,我能够通过转义新行实现这一点,我将编辑问题以显示这一点。真奇怪。我用你的代码测试了一个精简的函数,它在ISE和控制台中都能工作。我的环境是win7x64,ps5.1。//我建议您发布一个经过消毒的示例,说明问题所在。//当我从脚本中调用它时,它也能正常工作。您是否意外地将“`n”写为“`n”?或者是否将字符串括在单引号中?谢谢您完整、清晰的响应,这很有意义。在与一位同事交谈后,我们得出了类似的结论,认为用户希望他们在提示符中键入的内容会被逐字处理,而不是意外插入。是的,我认为传递哈希表更聪明,我当时认为我必须处理来自调用方的字符串,但还有另一种方法。