为什么我的值0布尔返回true? [英] Why is my boolean of value 0 returning true?

查看:466
本文介绍了为什么我的值0布尔返回true?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直工作在一些PowerShell脚本,并发现了一个有点奇怪。 我有一个接受4强制参数的脚本:两个字符串和两个布尔

。\ [脚本名称] [字符串1] [字符串2] [bool1] [BOOL2]

这工作得很好,和我检查,他们都被正确传递。

不过,我发现东西的时候PowerShell的请求参数比较奇怪;它同时设置布尔值设置为true。

 。\ [脚本名称] [字符串1] [字符串2]
请输入bool1:0
请输入boo2:0
 

据然后运行该脚本仿佛bool1和BOOL2设置为true,而不是我所设定他们。我有真正的传球在各种不同的东西,它总是会导致如此。

我不能确定,为什么发生这种情况,并想知道是否有人遇到一个原因或解决这个离奇的问题!

我还发现,任务计划程序也有类似的问题。 与设置它

的PowerShell - 文件[scriptlocation] [字符串1] [字符串2] [bool1] [BOOL2]

例如:

  

PowerShell的 - 文件C:\ script1.ps1C:\ fileOne.txtC:\文件夹10 0

这两个布尔来通过字符串。

解决方案

这个博客由Jeffrey Snover提供的PowerShell中布尔的行为的一些见解。下面是摘录,他在那里创建了一个简单的功能测试,以返回true或false取决于输入参数:

  PS>测试0
真正
PS>测试0
假
PS>测试1
真正
PS>测试0.0
假
PS>测试为0x0
假
PS>测试0MB
假
PS>测试0KB
假
PS>测试0D
假
PS>测试0.00000001
真正
 

  

0,因为它是一个字符串是TRUE,并且它具有1的长度是0   假,因为它是一个数字,该数字是0 PowerShell中,任何   其计算结果为0号是假,每一个非零数字是   真正。这个例子显示了一个浮点零,一个十六进制   零,0兆,0公斤,0小数,也有各种各样的零,而是   PowerShell中,他们都评价为FALSE。

在没有任何样品code这是很难说究竟发生了什么,但我们可以说的是,你的输入不被认定为为零的Powershell。也许这是一个字符串?如果你使用读主机来获取用户输入这将是真实的。这里有一个例子:

  PS C:\> $测试=读主机输入
输入:0
PS C:\> $ test.GetType()

IsPublic IsSerial名称基本类型
-------- -------- ---- --------
真真字符串System.Object的

PS C:\>测试$测试
真正

PS C:\> $测试= [的Int32] $测试
PS C:\>测试$测试
假
 

您可以检查通过使用的GetType()对有问题的变量,并修复它可能是显式地强制转换为所需的类型一件简单的事情。

我越读你的问题 - 除非我误解了它 - 这似乎解决您的问题。尤其是当你评论,你一直在传递各种不同的东西为已任非零长度字符串将评估为true,在这种情况下。

  PS C:\> $ anotherTest =42
PS C:\>测试$ anotherTest
真正
PS C:\> $ anotherTest = [的Int32] $ anotherTest
PS C:\>测试$ anotherTest
真正
 


编辑:好吧,我现在,我有一些想法你的环境是什么样的工作更上一个问题位。首先,一切我上面告诉你是真心的,所以请不要忽略它。您遇到的问题是,布尔类型转换处理PowerShell的强制提示输入的方式,是不是很明显。

所以有些情况已经发生这种code片断:

 参数
(
    [参数(强制= $真)] [布尔] $ myBool
)
写主机$ myBool
 

当您使用命令行提交的变量PowerShell中的强制性参数提示反而会导致以下结果:

  PS C:\> \ script.ps1
cmdlet的script.ps1在命令管道位置1
供给值以下参数:
myBool:0
真正
 

让我重新迭代:在PowerShell中,是一个空的长度并不是所有的字符串值为true 这包括0,这包括字符串。但是,什么是问题?我们已经明确地宣布我们的变量作为布尔,所以应该明白我的意思是0,对不对?

错误。一个相当不幸的情况被创建,我们正在期待一个布尔值,或者至少是一个字符串,当我们设置了输入提示。我们确实最终得到了布尔,但要记住发生在非空字符串是什么,当我们将它们转换为布尔变量?该类型转换为BOOL被应用到文字输入您设置的提示,这是不是一个数字类型。由于输入是一个非空的长度,所述布尔转换的计算结果为真。你基本上是在执行此操作:

  PS C:\> [布尔] $ myBool = [布尔]为0
PS C:\> $ myBool
真正
 

的最大问题在于,由于我们已经转换成我们的变量为布尔,字符串已经被消耗掉,我们只是留下了值1,或真。所以,你的0的字面变成1。我们不能让0回来了。我们应该做什么?我将列出两个选项:

  • 设置的变量作为 [INT] 键入代替 [布尔] 。布尔转换消耗的0字符串,并把它变成一个1,那么为什么不使用的一个类型不会的做到这一点? PowerShell的理解数字0和1为真与假,所以你可以使用任何数值类型。

例如与输出:

 参数
(
    [参数(强制= $真)] [INT] $ myBool
)
写主机$ myBool

PS C:\> \ script1.ps1
cmdlet的script1.ps1在命令管道位置1
供给值以下参数:
myBool:0
0
 

  • 如果您使用的是布尔变量的逻辑交换机,考虑 [转] 参数类型来代替。交换机总是为false,除非你明确地设置。你不应该永远暴露在提示这种方式,这样你就不会遇到这个问题。更多信息<一个href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd878252%28v=vs.85%29.aspx">here.

I've been working on some PowerShell scripts and found something a little odd. I have a script that accepts 4 mandatory parameters: two strings and two Booleans.

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

This works fine, and I've checked that they are all being passed correctly.

However, I've found something rather strange when PowerShell asks for parameters; it sets both booleans to true.

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

It then runs the script as if bool1 and bool2 were set to true, and not to what I've set them to. I have true passing in all sorts of different things, and it always results in true.

I'm unsure as to why this is happening, and wanted to know if anyone has come across a cause or solution to this bizarre problem!

I've also found that the Task Scheduler has a similar issue. Set it up with

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

example:

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

Both booleans come through as strings.

解决方案

This blog by Jeffrey Snover offers some insight on the behavior of booleans in Powershell. Below is an excerpt, where he creates a simple function "test" to return true or false depending on the input parameter:

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" is TRUE because it is a STRING and it has a length of 1. 0 is FALSE because it is a number and that number is 0. In PowerShell, any number which evaluates to 0 is FALSE and every non-zero number is TRUE. The example shows you a floating point zero, a hexadecimal zero, 0 megs, 0 kilos, 0 decimal, there are all sorts of zeros but to PowerShell, they all evaluate to FALSE.

Without any sample code it is hard to say exactly what is happening, but what we can say is that your input isn't being identified as zero by Powershell. Perhaps it is a string? This would be true if you used Read-Host to get user input. Here's an example:

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

You can check by using GetType() on the variable in question, and fixing it may be a simple matter of explicitly casting to the desired type.

The more I read your question -- unless I've misunderstood it -- this seems to address your problems. Especially where you comment that you've been "passing in all sorts of different things" as any non-zero length string would evaluate to true in this context.

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


Edit: Alright, I've worked a bit more on the problem now that I have some idea what your environment is. First, everything I told you above is true, so please don't disregard it. The problem you're experiencing is that the boolean type conversion is handling the powershell mandatory prompt input in a way that isn't immediately obvious.

So some situation exists where this code snippet:

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

Will cause the following result when you use powershell's mandatory parameter prompt instead of submitting the variable on the command line:

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

Let me re-iterate: In Powershell, all strings that are not of a null length evaluate to true. This includes "0", and this includes string literals. But what's the problem? We've already explicitly declared our variable as a bool, so it should understand that I mean 0, right?

Wrong. A rather unfortunate situation is created where we're expecting a bool, or at least a string, when we set our input to the prompt. We do indeed eventually get out bool, but remember what happens to non-null strings when we convert them to bools? The type conversion to bool is being applied to the literal input you set at the prompt, which is not a numeric type. Since the input is of a non-null length, the bool conversion evaluates to true. You are essentially performing this operation:

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

The big problem with this is that since we've already converted our variable to a bool, the string has been consumed and we're just left with the value 1, or True. So your "0" literally turned into 1. We can't get the 0 back anymore. What should we do? I'll list a couple of options:

  • Set your variable as an [int] type instead of a [bool]. The bool conversion consumed the "0" string and turned it into a 1, so why not use a type that won't do that? Powershell understands numerical 0s and 1s to be true and false, so you can use any numerical type.

Example with output:

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

  • If you are using the bools as logic switches, consider the [switch] parameter type instead. Switches always evaluate to false unless you explicitly set them. You shouldn't ever expose the prompt this way, so you won't encounter this problem. More info here.

这篇关于为什么我的值0布尔返回true?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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