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

时间:2013-08-29 16:14:20

标签: .net powershell parameters boolean powershell-v3.0

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

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

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

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

.\[scriptname] [string1] [string2]
please enter bool1: 0
please enter boo2: 0

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

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

我还发现任务计划程序有类似的问题。 用

设置

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

示例:

  

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

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

2 个答案:

答案 0 :(得分:14)

Jeffrey Snover的

This blog提供了一些关于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
  

“0”为TRUE,因为它是一个STRING,长度为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

您可以使用GetType()检查相关变量,修复它可能只是显式转换为所需类型。

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

PS C:\> $anotherTest = "42"
PS C:\> test $anotherTest
TRUE
PS C:\> $anotherTest = [Int32]$anotherTest
PS C:\> test $anotherTest
TRUE

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

因此,在某些情况下,此代码段存在:

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

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

PS C:\> .\script.ps1 
cmdlet script.ps1 at command pipeline position 1
Supply values for the following parameters: 
myBool: 0 
True

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

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

PS C:\> [bool]$myBool = [bool]"0"
PS C:\> $myBool
True

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

  • 将变量设置为[int]类型,而不是[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
  • 如果您使用bools作为逻辑开关,请考虑使用[switch]参数类型。除非您明确设置,否则开关总是评估为false。您不应该以这种方式公开提示,因此您不会遇到此问题。更多信息here

答案 1 :(得分:0)

如果你的函数不接受boolean参数,这可能解释了为什么会发生这种情况(Hyper Anthony解释得很好)。

那么,你的脚本是否有param([string] x1,[string [x2],[bool] y1,[bool] y2)声明类型?在那种情况下,y1和y2将是布尔值,但如果不是,则可能被视为具有值0的字符串,在这种情况下,它被视为" 0"不等于0