为什么我的布尔值0返回true?

Haz*_*z22 6 .net parameters powershell boolean powershell-3.0

我一直在研究一些PowerShell脚本,发现有些奇怪的东西.我有一个脚本,接受4个强制参数:两个字符串和两个布尔值.

.\[scriptname] [string1] [string2] [bool1] [bool2]

这很好,我已经检查过它们都正确传递了.

但是,当PowerShell请求参数时,我发现了一些相当奇怪的东西; 它将两个布尔值设为真.

.\[scriptname] [string1] [string2]
please enter bool1: 0
please enter boo2: 0
Run Code Online (Sandbox Code Playgroud)

然后它运行脚本,好像bool1和bool2设置为true,而不是我设置它们.我真实地传递了各种不同的东西,它总是真实的.

我不确定为什么会这样,并想知道是否有人遇到过这个奇怪问题的原因或解决方案!

我还发现Task Scheduler有类似的问题.用它来设置

powershell -file [scriptlocation] [string1] [string2] [bool1] [bool2]

例:

powershell -file"C:\ script1.ps1""c:\ fileOne.txt""c:\ folder1"0 0

两个布尔都是以字符串形式出现的.

Ant*_*ace 14

Jeffrey Snover撰写的这篇博客提供了一些关于Powershell中布尔行为的见解.下面是一段摘录,他创建了一个简单的函数"test",根据输入参数返回true或false:

PS> test "0"
TRUE
PS> test 0
FALSE
PS> test 1
TRUE
PS> test 0.0
FALSE
PS> test 0x0
FALSE
PS> test 0mb
FALSE
PS> test 0kb
FALSE
PS> test 0D
FALSE
PS> test 0.00000001
TRUE
Run Code Online (Sandbox Code Playgroud)

"0"是正确的,因为它是一个字符串,它具有1的长度为0是FALSE,因为它是一个数字,该数字是0.在PowerShell中,任何数量的计算结果为0为FALSE且每一个非零数是真正.该示例显示了一个浮点零,一个十六进制零,0兆,0千,0十进制,有各种零但是对于PowerShell,它们都评估为FALSE.

没有任何示例代码,很难确切地说出发生了什么,但我们可以说,你的输入并没有被Powershell识别为零.也许这是一个字符串?如果您曾经Read-Host获得用户输入,那将是真实的.这是一个例子:

PS C:\> $test = Read-Host "Input"
Input: 0
PS C:\> $test.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

PS C:\> test $test
TRUE

PS C:\> $test = [Int32]$test
PS C:\> test $test
FALSE
Run Code Online (Sandbox Code Playgroud)

您可以通过使用有GetType()问题的变量进行检查,修复它可能是一个简单的问题,明确地转换为所需的类型.

我越读你的问题 - 除非我误解了它 - 这似乎解决了你的问题.特别是当你评论你一直在"传递各种不同的东西"时,因为任何非零长度的字符串在这种情况下都会被评估为真.

PS C:\> $anotherTest = "42"
PS C:\> test $anotherTest
TRUE
PS C:\> $anotherTest = [Int32]$anotherTest
PS C:\> test $anotherTest
TRUE
Run Code Online (Sandbox Code Playgroud)

编辑:好的,我现在已经对这个问题有了更多的了解,因为我知道你的环境是什么.首先,我告诉你的一切都是真的,所以请不要忽视它.您遇到的问题是布尔类型转换正在以一种不是很明显的方式处理powershell强制提示输入.

因此,这段代码片段存在一些情况:

param
(
    [Parameter(mandatory=$true)][bool]$myBool
)
Write-Host $myBool
Run Code Online (Sandbox Code Playgroud)

使用powershell的强制参数提示而不是在命令行上提交变量时,将导致以下结果:

PS C:\> .\script.ps1 
cmdlet script.ps1 at command pipeline position 1
Supply values for the following parameters: 
myBool: 0 
True
Run Code Online (Sandbox Code Playgroud)

让我重新迭代:在Powershell中,所有不是null长度的字符串都会计算为true.这包括"0",这包括字符串文字.但是问题是什么?我们已经明确地将变量声明为a bool,所以它应该理解我的意思是0,对吗?

错误.当我们将输入设置为提示时,会产生一个相当不幸的情况,即我们期望一个bool,或者至少是一个字符串.我们确实最终得到了bool,但是还记得当我们将它们转换为bools时,非null字符串会发生什么?类型转换为bool将应用于您在提示符处设置的文字输入,该输入不是数字类型.由于输入的长度为非null,因此bool转换的计算结果为true.您实质上是在执行此操作:

PS C:\> [bool]$myBool = [bool]"0"
PS C:\> $myBool
True
Run Code Online (Sandbox Code Playgroud)

这个问题的一大问题是,由于我们已经将变量转换为bool,因此字符串已被消耗,我们只剩下值1或True.所以你的"0"字面上变成了1.我们不能再回到0了.我们应该做什么?我将列出几个选项:

  • 将变量设置为[int]类型而不是a [bool].bool转换消耗了"0"字符串并将其转换为1,那么为什么不使用会这样做的类型呢?Powershell将数字0和1理解为真和假,因此您可以使用任何数字类型.

输出示例:

param
(
    [Parameter(mandatory=$true)][int]$myBool
)
Write-Host $myBool

PS C:\> .\script1.ps1
cmdlet script1.ps1 at command pipeline position 1
Supply values for the following parameters:
myBool: 0
0
Run Code Online (Sandbox Code Playgroud)
  • 如果您使用bools作为逻辑开关,请考虑[switch]参数类型.除非您明确设置,否则开关总是评估为false.您不应该以这种方式公开提示,因此您不会遇到此问题.更多信息在这里.