对于PowerShell cmdlet,是否可以始终将脚本块传递给字符串参数? [英] For PowerShell cmdlets, can I always pass a script block to a string parameter?

查看:146
本文介绍了对于PowerShell cmdlet,是否可以始终将脚本块传递给字符串参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm looking at the document of Rename-Item and there is an example like this.

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

此示例显示如何使用替换"运算符重命名多个 文件,即使NewName参数不接受通配符 字符.

This example shows how to use the Replace operator to rename multiple files, even though the NewName parameter does not accept wildcard characters.

此命令将当前目录中的所有.txt文件重命名为 .log.

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

该命令使用Get-ChildItem cmdlet来获取其中的所有文件 具有.txt文件扩展名的当前文件夹.然后呢 使用管道运算符(|)将这些文件发送到Rename-Item.

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

NewName的值是一个脚本块,该脚本块在该值之前运行 提交给NewName参数.

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

注意最后一句话:

NewName的值是一个脚本块,该脚本块在将值提交给NewName参数之前运行.

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

实际上NewName是字符串:

[-NewName] <String>

那么这是否意味着当所需的参数类型为字符串时,我总是可以使用脚本块吗?

So does that means I can always use a script block when the required parameter type is a string?

推荐答案

延迟绑定脚本块参数 隐式 >功能:

Delay-bind script-block arguments are an implicit feature that:

  • 旨在接受管道输入的参数一起使用

  • only works with parameters that are designed to take pipeline input,

  • 任何类型的除了以下,在这种情况下会发生常规参数绑定 [1] :

  • [scriptblock]
  • [object](但是,[psobject]起作用,因此[pscustomobject]也起作用)
  • (未指定类型),实际上与[object]
  • 相同
  • [scriptblock]
  • [object] ([psobject], however, does work, and therefore [pscustomobject] too)
  • (no type specified), which is effectively the same as [object]

这些参数是否接受通过 value (ValueFromPipelineBy)或通过属性名称(ValueFromPipelineByPropertyName)进行的管道输入.

whether such parameters accept pipeline input by value (ValueFromPipelineBy) or by property name (ValueFromPipelineByPropertyName), is irrelevant.

通过脚本块传递的代替类型合适的自变量每个输入对象 ;将为每个管道对象评估脚本块,该脚本块通常可以在$_中以$_的形式在脚本块内部进行访问,并且假定脚本块的 output -假定其与参数类型相符-用作参数.

enables per-input-object transformations via a script block passed instead of a type-appropriate argument; the script block is evaluated for each pipeline object, which is accessible inside the script block as $_, as usual, and the script block's output - which is assumed to be type-appropriate for the parameter - is used as the argument.

  • 由于按照定义,此类临时脚本块与您要定位的参数类型不匹配,因此在传递它们时必须始终显式使用参数名称.

延迟绑定脚本块无条件提供对管道输入对象的访问,即使该参数通常受给定的管道对象绑定,如果它定义为ValueFromPipelineByPropertyName,并且该对象缺少该名称的属性.

Delay-bind script blocks unconditionally provide access to the pipeline input objects, even if the parameter would ordinarily not be bound by a given pipeline object, if it is defined as ValueFromPipelineByPropertyName and the object lacks a property by that name.

  • 这将启用诸如以下对Rename-Item的调用之类的技术,其中,通常将Get-Item的管道输入绑定到-LiteralPath参数,但是将脚本块传递给-NewName-通常仅绑定到具有.NewName属性的输入对象-启用对同一管道对象的访问,从而从输入文件名派生目标文件名:
    • Get-Item file | Rename-Item -NewName { $_.Name + '1' } # renames 'file' to 'file1';输入绑定到 -LiteralPath(隐式) -NewName脚本块.
    • This enables techniques such as the following call to Rename-Item, where the pipeline input from Get-Item is - as usual - bound to the -LiteralPath parameter, but passing a script block to -NewName - which would ordinarily only bind to input objects with a .NewName property - enables access to the same pipeline object and thus deriving the destination filename from the input filename:
      • Get-Item file | Rename-Item -NewName { $_.Name + '1' } # renames 'file' to 'file1'; input binds to both -LiteralPath (implicitly) and the -NewName script block.

      注意:例如,与传递给ForEach-ObjectWhere-Object的脚本块不同,延迟绑定脚本块在 child 变量范围内运行 [2] ,这意味着您不能直接修改调用者的变量,例如在输入对象之间增加计数器.
      解决方法是,使用在调用方作用域中声明的[ref]类型变量,并在脚本块内访问其.Value属性-请参见这个答案为例.

      Note: Unlike script blocks passed to ForEach-Object or Where-Object, for example, delay-bind script blocks run in a child variable scope[2], which means that you cannot directly modify the caller's variables, such as incrementing a counter across input objects.
      As a workaround, use a [ref]-typed variable declared in the caller's scope and access its .Value property inside the script block - see this answer for an example.

      [1]错误条件:

      • 如果您错误地尝试将脚本块传递给不是管道绑定或[scriptblock]-或[object]类型(未键入)的参数 常规参数绑定:

      • If you mistakenly attempt to pass a script block to a parameter that is either not pipeline-binding or is [scriptblock]- or [object]-typed (untyped), regular parameter-binding occurs:

      • 在流水线输入处理开始之前(如果有的话)在一次中传递脚本块.
        也就是说,脚本块作为(可能是转换的)传递,并且没有评估发生.
        • 对于类型为[object][scriptblock]的参数/可以转换为脚本块的委托类型(例如System.Func),脚本块将按原样绑定 .
        • 对于(非管道绑定)[string]类型的参数,脚本块的文字内容作为字符串值传递.
        • 对于所有其他类型,参数绑定(以及整个命令)将简单地失败,因为无法从脚本块进行转换.
        • The script block is passed once, before pipeline-input processing begins, if any.
          That is, the script block is passed as a (possibly converted) value, and no evaluation happens.
          • For parameters of type [object] or [scriptblock] / a delegate type such as System.Func that is convertible to a script block, the script block will bind as-is.
          • In the case of a (non-pipeline-binding) [string]-typed parameter, the script block's literal contents is passed as the string value.
          • For all other types, parameter binding - and therefore the command as a whole - will simply fail, since conversion from a script block is not possible.

          如果您忽略提供管道输入,而将延迟绑定脚本块传递给支持的管道绑定参数,则会得到以下错误:

          If you neglect to provide pipeline input while passing a delay-bind script block to a pipeline-binding parameter that does support them, you'll get the following error:

          • 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]此差异正在此GitHub问题中进行讨论

          这篇关于对于PowerShell cmdlet,是否可以始终将脚本块传递给字符串参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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