Powershell陷阱

26 浏览
0 Comments

Powershell陷阱

你遇到了哪些PowerShell的陷阱呢? 🙂

我的例子如下:

# -----------------------------------
function foo()
{
    @("text")
}
# 预期是1,实际上是4。
(foo).length
# -----------------------------------
if(@($null, $null))
{
    Write-Host "预期能运行到这里,实际上也可以运行到这里。"
}
if(@($null))
{
    Write-Host "预期能运行到这里,但是永远不会。"
}
# -----------------------------------
function foo($a)
{
    # 我以为这样是对的。
    #if($a -eq $null)
    #{
    #    throw "你不能将$null作为参数传递。"
    #}
    # 实际上应该是这样的:
    if($null -eq $a)
    {
        throw "你不能将$null作为参数传递。"
    }
}
foo @($null, $null)
# -----------------------------------
# 有try/catch,但是没有报告调用栈。
function foo() 
{
   bar
}
function bar() 
{
  throw "测试"
}
# 预期结果:
#  在bar()行:XX
#  在foo()行:XX
#  
# 实际结果类似于:
#  在bar()行:XX
foo

希望知道你们遇到的陷阱,以便避免它们的影响 🙂

0
0 Comments

在使用PowerShell时,有一个常见的错误是不正确处理表达式,默认情况下会将其写入到管道中。当你没有意识到某个函数返回一个值时,这会非常令人烦恼。

例如,考虑以下函数示例:

function example() {
  param ( $p1 )
  if ( $p1 ) {
    42
  }
  "done"
}

在上面的示例中,我们定义了一个名为example的函数,它接受一个参数$p1。如果$p1为真,函数会返回值42,否则返回字符串"done"。

现在,假设我们调用这个函数并传入一个为真的参数:

PS> example $true

结果会是:

42
"done"

这是因为我们没有正确处理函数返回的值。实际上,当我们调用函数时,函数的返回值会被写入到默认的输出管道中。在这种情况下,返回值42被输出了出来,然后才是字符串"done"。

要解决这个问题,我们需要显式地处理函数的返回值。我们可以使用变量来存储返回值,或者使用管道操作符将其发送到其他命令中。

以下是解决这个问题的两种方法:

1. 使用变量存储返回值:

$value = example $true

现在,返回值42会被存储在变量$value中,而不会被写入到默认的输出管道中。

2. 使用管道操作符将返回值发送到其他命令中:

example $true | Out-Null

在这个例子中,我们使用了Out-Null命令将返回值42丢弃,而不会将其写入到默认的输出管道中。

通过正确处理函数的返回值,我们可以避免这个PowerShell陷阱,并确保程序的行为符合预期。

0
0 Comments

Powershell陷阱:无法在空值表达式上调用方法的问题

在上述代码中,当Get-ChildItem命令没有返回任何结果时,$files被赋值为$null。然后,foreach语句将会对一个标量值进行循环,即使这个标量值是$null。在循环中,当尝试调用$file.Fullname.substring(2)时,会出现错误提示"无法在空值表达式上调用方法"。

为了解决这个问题,可以将Get-ChildItem命令的结果放入@()中,即@(Get-ChildItem . -inc *.extdoesntexist)。这样,无论命令返回0个、1个还是多个结果,都将得到一个数组。需要注意的是,如果命令返回的本身已经是数组,使用@(命令)将不会产生额外的数组包装。

值得一提的是,从PowerShell V3开始,foreach不再仅对$null进行迭代。也就是说,对于foreach( $d in $null ) { "This never displays!" },将会按照字面意思执行,不会进入循环。然而,强制将结果转换为数组的做法仍然非常常见,并且是一个良好的编程习惯。

0
0 Comments

Powershell pitfalls(Powershell陷阱)的问题是出现在使用函数参数时的语法错误。问题的原因是在调用函数时,参数使用了括号,导致将参数视为数组而不是多个单独的参数。解决方法是在调用函数时去除括号,直接使用空格分隔多个参数。

在Powershell中,函数的参数可以使用括号将多个参数括起来,以便传递给函数。然而,在上述示例中,函数foo被调用时使用了括号,导致将参数1和参数2视为一个数组,而不是两个单独的参数。因此,当函数试图使用第二个参数时,会抛出错误。

为了解决这个问题,我们需要将函数调用的括号去除,直接使用空格分隔多个参数。这样,函数foo将会正确接收两个单独的参数。

这个问题让人想起了VB和VBScript处理参数括号的方式。在VB和VBScript中,使用括号调用函数和不使用括号调用函数是不同的,使用括号调用函数会忽略返回值并强制使用括号,而不使用括号调用函数则不能使用括号。

总结起来,当在Powershell中调用函数时,需要注意不要使用括号将多个参数括起来,而是使用空格分隔多个参数。这样可以避免出现类似的语法错误。

0