gpt4 book ai didi

powershell - 对于PowerShell cmdlet,是否可以始终将脚本 block 传递给字符串参数?

转载 作者:行者123 更新时间:2023-12-03 09:39:29 24 4
gpt4 key购买 nike

我正在查看PowerShell的Rename-Item cmdlet的文档,并且有一个这样的示例。

Get-ChildItem *.txt | Rename-Item -NewName { $_.name -Replace '\.txt','.log' }

This example shows how to use the Replace operator to rename multiplefiles, even though the NewName parameter does not accept wildcardcharacters.

This command renames all of the .txt files in the current directory to.log.

The command uses the Get-ChildItem cmdlet to get all of the files inthe current folder that have a .txt file name extension. Then, ituses the pipeline operator (|) to send those files to Rename-Item .

The value of NewName is a script block that runs before the value issubmitted to the NewName parameter.


注意最后一句话:
NewName的值是一个脚本块,在将值提交给NewName参数之前运行。
实际上 NewName是一个字符串:
[-NewName] <String>
那么这是否意味着当所需的参数类型为字符串时,我总是可以使用脚本块吗?

最佳答案

# Delay-bind script-block argument:
# The code inside { ... } is executed for each input object ($_) and
# the output is passed to the -NewName parameter.
... | Rename-Item -NewName { $_.Name -replace '\.txt$','.log' }
上面的调用显示了 延迟绑定(bind)脚本块({ ... })参数的应用,该参数是 隐式功能,它具有:
  • 仅适用于旨在接受管道输入的参数,

  • 除了以下以外的任何类型,在这种情况下都会进行常规参数绑定(bind)[1]:
  • [scriptblock]
  • [object](但是[psobject]确实起作用,因此也适用[pscustomobject])
  • (未指定类型),实际上与[object]
  • 相同

  • 此类参数是否接受按值(ValueFromPipelineBy)或按属性名(ValueFromPipelineByPropertyName)接受管道输入都是无关紧要的。

  • 通过传递的脚本块而不是类型合适的参数来启用按输入对象的转换;将为每个管道对象评估脚本块,该脚本块通常可以通过$_在脚本块内部进行访问,并且脚本块的输出(假定为参数的类型正确)用作参数。
  • 由于定义上的此类即席脚本块与您要定位的参数类型不匹配,因此在传递它们时必须始终使用参数名称
  • 延迟绑定(bind)脚本块无条件提供对管道输入对象的访问,即使该参数通常不被给定的管道对象绑定(bind),即使它被定义为ValueFromPipelineByPropertyName并且该对象缺少该名称的属性也是如此。
  • 这将启用诸如以下对Rename-Item的调用之类的技术,其中Get-Item的管道输入(通常)绑定(bind)到-LiteralPath参数,但是将脚本块传递给-NewName-通常只绑定(bind)到具有.NewName属性的输入对象-启用对同一管道对象的访问,从而从输入文件名派生目标文件名:
  • Get-Item file | Rename-Item -NewName { $_.Name + '1' } # renames 'file' to 'file1';输入同时绑定(bind)到-LiteralPath-NewName脚本块。

  • 注意:例如,与传递给ForEach-ObjectWhere-Object的脚本块不同, delay-bind脚本块在子变量范围 [2]中运行,这意味着您无法直接修改调用者的变量,例如在输入中增加计数器对象。
    解决方法是,使用在调用方作用域中声明的[ref]类型的变量,并在脚本块中访问其.Value属性-有关示例,请参见this answer


  • [1]错误条件:
  • 如果您错误地尝试将脚本块传递给非管道绑定(bind)或[scriptblock]-或[object]类型(无类型)的参数,则会发生常规参数绑定(bind):
  • (如果有的话)在开始管道输入处理之前,将脚本块传递一次。
    即,脚本块作为(可能是转换的)值传递,并且不进行评估。
  • 对于[object][scriptblock]类型的参数/可转换为脚本块的委托(delegate)类型(例如System.Func),脚本块将按原样绑定(bind)。
  • 对于(非管道绑定(bind))[string]类型的参数,脚本块的文字内容作为字符串值传递。
  • 对于所有其他类型,由于无法从脚本块进行转换,因此参数绑定(bind)(因此整个命令)将仅失败。


  • 如果您在将延迟绑定(bind)脚本块传递给确实支持它们的管道绑定(bind)参数时忽略了提供管道输入,则会收到以下错误:
  • Cannot evaluate parameter '<name>' because its argument is specified as a script block and there is no input. A script block cannot be evaluated without input.


  • [2]这个差异正在 this GitHub issue中讨论。

    关于powershell - 对于PowerShell cmdlet,是否可以始终将脚本 block 传递给字符串参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52805820/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com