【问题标题】:How do I write a PowerShell script that accepts pipeline input?如何编写接受管道输入的 PowerShell 脚本?
【发布时间】:2010-10-27 11:41:28
【问题描述】:

我正在尝试编写一个可以获取管道输入的 PowerShell 脚本(并且预计会这样做),但尝试类似

ForEach-Object {
   # do something
}

从命令行使用脚本时实际上不起作用,如下所示:

1..20 | .\test.ps1

有办法吗?

注意:我知道函数和过滤器。这不是我要找的。​​p>

【问题讨论】:

    标签: powershell


    【解决方案1】:

    在 v2 中,您还可以接受管道输入(通过 propertyName 或 byValue),添加参数别名等:

    function Get-File{
        param(  
        [Parameter(
            Position=0, 
            Mandatory=$true, 
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true)
        ]
        [Alias('FullName')]
        [String[]]$FilePath
        ) 
    
        process {
           foreach($path in $FilePath)
           {
               Write-Host "file path is: $path"
           }
        }
    }
    
    
    # test ValueFromPipelineByPropertyName 
    dir | Get-File
    
    # test ValueFromPipeline (byValue) 
    
    "D:\scripts\s1.txt","D:\scripts\s2.txt" | Get-File
    
     - or -
    
    dir *.txt | foreach {$_.fullname} | Get-File
    

    【讨论】:

    • 仍然是一个函数,而不是一个脚本。见stackoverflow.com/questions/885349/…的评论。
    • 没什么大不了的,将函数体保存在脚本文件中并通过管道传输到脚本:dir | .\Get-File.ps1
    • 其实你可以把 param() 块放在脚本的顶部,而不需要声明脚本的本地函数。
    【解决方案2】:

    这可行,可能还有其他方法可以做到:

    foreach ($i in $input) {
        $i
    }
    

    17:12:42 PS>1..20 | .\cmd-input.ps1
    1
    2
    3
    -- 剪辑 --
    18
    19
    20

    搜索“powershell $input variable”,您将找到更多信息和示例。
    一对夫妇在这里:
    PowerShell Functions and Filters PowerShell Pro!
    (请参阅“使用 PowerShell 特殊变量“$input””一节)
    “脚本、函数和脚本块都可以访问 $input 变量,该变量为传入管道中的元素提供枚举器。”

    $input gotchas « Dmitry’s PowerBlog PowerShell and beyond
    “...基本上 $input 在一个枚举器中,它提供对您拥有的管道的访问。”

    对于 PS 命令行,而不是 DOS 命令行 Windows 命令处理器。

    【讨论】:

    • 是时候进行一点 necro-ing... 只是为了让任何徘徊并阅读此内容的人受益,DOS 在每个版本的 Windows 上仍然可用。 64 位或 32 位。
    • EBGreen, ntvdm,这是 Windows NT 所拥有的 DOS VM,在 64 位系统上不再存在。 cmd.exe 不是 DOS;它是 Windows 命令处理器,除了黑底灰字之外,与 DOS 没有任何共同之处。
    【解决方案3】:

    您可以编写一个过滤器,它是这样一个函数的特例:

    filter SquareIt([int]$num) { $_ * $_ }
    

    或者你可以像这样创建一个类似的函数:

    function SquareIt([int]$num) {
      Begin {
        # Executes once before first item in pipeline is processed
      }
    
      Process {
        # Executes once for each pipeline object
        $_ * $_
      }
    
      End {
        # Executes once after last pipeline object is processed
      }
    }
    

    以上作为交互式函数定义工作,或者如果在脚本中可以点缀到您的全局会话(或其他脚本)中。但是,您的示例表明您需要一个脚本,所以这里它位于一个可直接使用的脚本中(不需要点):

      --- Contents of test.ps1 ---
      param([int]$num)
    
      Begin {
        # Executes once before first item in pipeline is processed
      }
    
      Process {
        # Executes once for each pipeline object
        $_ * $_
      }
    
      End {
        # Executes once after last pipeline object is processed
      }
    

    在 PowerShell V2 中,这与“高级函数”有所不同,它嵌入了具有与编译的 cmdlet 相同的参数绑定功能的函数。有关差异的示例,请参阅此blog post。另请注意,在此高级功能案例中,您不使用 $_ 来访问管道对象。借助高级功能,管道对象可以像使用 cmdlet 一样绑定到参数。

    【讨论】:

    • 我知道过滤器,但我想将脚本用作管道中的元素,而不是脚本中定义的函数。不过,谢谢。
    • 进程块就是你想要的。它的优点是不阻塞管道。
    • 如果你指定一个参数,你应该使用它。我认为它是某种参数原型的一部分,并且想知道为什么不使用它,或者是否可以使用它来代替 THIS。浪费的周期。不过还是喜欢这个答案;)
    【解决方案4】:

    以下是使用管道输入的最简单的脚本/函数示例。每个行为都与管道到“echo”cmdlet 的行为相同。

    作为脚本:

    # 回声管.ps1
      Begin {
        # Executes once before first item in pipeline is processed
      }
    
      Process {
        # Executes once for each pipeline object
        echo $_
      }
    
      End {
        # Executes once after last pipeline object is processed
      }
    
    # Echo-Pipe2.ps1
    foreach ($i in $input) {
        $i
    }
    

    作为函数:

    Function Echo-Pipe {
      Begin {
        # Executes once before first item in pipeline is processed
      }
    
      Process {
        # Executes once for each pipeline object
        echo $_
      }
    
      End {
        # Executes once after last pipeline object is processed
      }
    }
    
    Function Echo-Pipe2 {
        foreach ($i in $input) {
            $i
        }
    }
    

    例如

    PS > . theFileThatContainsTheFunctions.ps1 # This includes the functions into your session
    PS > echo "hello world" | Echo-Pipe
    hello world
    PS > cat aFileWithThreeTestLines.txt | Echo-Pipe2
    The first test line
    The second test line
    The third test line
    

    【讨论】:

    • 为什么要重申基思两年前给出的答案?
    • 他的回答包含以下问题: 它没有完全包含回答问题所必需的内容 - 平方是钝的。不需要函数参数,我们可以简单地使用$_。 “您可以编写一个过滤器,它是这样的函数的特例” - 没有语法意义,并且没有必要使用过滤器。
    • 这在 ubuntu 上对我有用。上面的答案没有。
    猜你喜欢
    • 2022-01-20
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 2023-03-28
    • 1970-01-01
    • 2014-02-25
    相关资源
    最近更新 更多