【问题标题】:New-Item messing up my variable PowerShell [duplicate]新项目弄乱了我的变量 PowerShell [重复]
【发布时间】:2021-05-06 20:01:41
【问题描述】:

我编写了一个非常简单的脚本来获取一个随机的空闲驱动器号。 该函数找到一个随机的空闲字母,创建一个具有该驱动器字母名称的新空文本文件,例如。 Q.txt 然后我将值返回为 $new_letter 但是当它从函数中出来时,新文件创建的路径是变量 C:\AppPack\Logs\Q.txt Q

的一部分

是不是 New-Item 弄乱了我的 $new_letter 变量?


function get_drive_letter()
{
$letter_acquired = $false
Do
{
$new_letter = Get-ChildItem function:[h-z]: -Name | ForEach-Object { if (!(Test-Path $_)){$_} } | random -Count 1 | ForEach-Object {$_ -replace ':$', ''}
    write-host ("RIGHT AFTER " + $new_letter)
    if (!(test-path "C:\AppPack\Logs\$new_letter.txt"))
    {    
    New-Item -Path C:\AppPack\Logs\ -Name "$new_letter.txt" -ItemType "file" 
    write-host ("FROM FUNCTION " + $new_letter)
    $letter_acquired = $true
    return $new_letter
     }
    
    
    else
    {
    write-host ("LETTER USED ALREADY")
    write-host ($new_letter)
    }
}
while($letter_acquired = $false)
}

$drive_letter = $null

$drive_letter = get_drive_letter
write-host ("RIGHT AFTER FUNCTION " + $drive_letter)

输出:

RIGHT AFTER Q
FROM FUNCTION Q
RIGHT AFTER FUNCTION C:\AppPack\Logs\Q.txt Q

【问题讨论】:

  • 函数返回函数中运行的所有命令的所有输出。
  • @js2010 我也更新了我的 Do- 虽然我不能只返回一个变量值吗?
  • 顺便说一句,while($letter_acquired = $false)while($false) 没有什么不同 - 你会希望 while($letter_acquired -eq $false)(我更喜欢 while(-not $letter_acquired))让它按照你想要的方式工作
  • 您必须隐藏所有其他命令的输出,例如new-item file5 > $null。 Return 并没有真正做到你认为的那样。只是从代码中分支出来。
  • 简而言之:任何输出——无论是来自 PowerShell 命令还是 .NET 方法调用——既不是在变量中捕获也不是重定向(通过管道或文件发送)是 隐式输出。要简单地丢弃此类输出,请使用$null = ...。如果您不丢弃此类输出,它将成为脚本或函数“返回值”(输出对象流)的一部分。请参阅 this answer 链接的副本。

标签: function powershell variables new-item


【解决方案1】:

PowerShell 函数输出所有内容,而不仅仅是return! 之后的表达式的结果!

您看到的附加文件路径是来自 New-Item ... 的输出 - 它为您刚刚创建的文件返回一个 FileInfo 对象。

您可以通过将输出分配给特殊的$null 变量来抑制输出:

# Output from New-Item will no longer "bubble up" to the caller
$null = New-Item -Path C:\AppPack\Logs\ -Name "$new_letter.txt" -ItemType "file"
return $new_letter

或者通过管道发送到Out-Null:

New-Item ... |Out-Null

或者通过将整个管道转换为[void]

[void](New-Item ...)

虽然我建议在调用站点明确处理不需要的输出,但您可以也可以通过提升技巧来解决此问题。

为了演示,考虑这个虚拟函数 - 假设我们从一位并不总是编写最直观的代码的同事那里“继承”它:

function Get-RandomSquare {
  "unwanted noise"

  $randomValue = 1..100 |Get-Random

  "more noise"

  $square = $randomValue * $randomValue

  return $square
}

上面的函数会输出3个对象——两个垃圾字符串一个接一个,后面是我们真正感兴趣的结果:

PS ~> $result = Get-RandomSquare
PS ~> $result
unwanted noise
more noise
6400

假设我们被告知要尽可能少地进行修改,但我们确实需要抑制垃圾输出。

为此,请将整个函数体嵌套在一个新的脚本块文字中,然后使用点源运算符 (.) 调用整个块 - 这会强制 PowerShell 在函数的 local 作用域,意味着任何变量赋值都保持:

function Get-RandomSquare {
  # suppress all pipeline output
  $null = . {
    "unwanted noise"
    $randomValue = 1..100 |Get-Random 
    "more noise"
    $square = $randomValue

    return $square
  }

  # variables assigned in the block are still available
  return $square
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2023-03-28
    相关资源
    最近更新 更多