增强管道的内容?

时间:2015-06-16 17:22:02

标签: powershell powershell-v3.0

假设你有一个使用7-zip压缩文件的命令,它接受来自管道的值:

Function New-Archive {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)][Alias('FullName')]
        [string[]]$Files,

        [string]$Archive='Archive.zip'
    )

    BEGIN {}
    PROCESS {
      Foreach ($File in $Files) {
        & 7z a -tZIP $Archive $File
      }
    }
    END {}
}

假设foo目录包含以下文件:a.txt,b.txt,c.txt

执行命令:

PS Foo> GCI | New-Archive

产生的输出类似于:

7-Zip [64] 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18

Scanning

Updating archive .\files.zip

Compressing  a.txt
Compressing  b.txt
Compressing  c.txt
Compressing  files.zip

Everything is Ok

解析输出,捕获压缩结果并将其添加到管道非常容易:

...
$output = & 7z a $Archive $File

#
# parse stdout; capture files that were compressed; convert to PsObject[] 
#
$output = $output[7..($output.Length-4)]
$output | foreach {
  $parts = $_ -split "\s+", 2
    New-Object -Type PSObject -Property @{
      Name = $parts[1]
    }
}

问题:

  1. 管道是否应包含原始内容(来自GCI),修改后的内容(来自7a),还是两者兼而有之?
  2. 如果两者都有,这是怎么做到的?
  3. 应将结果文件(Archive.zip)的路径添加到管道中,还是由函数返回?

2 个答案:

答案 0 :(得分:2)

Updating archive .\files.zip ... Compressing files.zip?在向Archive.zip添加Archive.zip时检查您的函数是否有案例,这应该会发出警告,例如复制自身。

关于管道 - 我认为您应该使用-passthru开关,如果存在开关,则将存档作为Get-Item结果(System.IO.FileInfo对象)返回,否则返回void。此外,如果您使用-AsJob标志,请将作业作为函数结果返回。

另外,如果您打算在7zip模块中使用存档,则需要指向它们的链接,可能是通用文件的子类型,或者只是文件,因为New-Archive正在生成一个存档,不是一组它们,管道似乎是多余的功能。

要点:

  1. 在这种情况下,修改内容或无效。
  2. 不是“两个”。
  3. 返回System.IO.FileInfo对象将解决这两个目标。
  4. 考虑添加一个-LogFile参数,该参数指示从7zip放置文本数据的位置。

答案 1 :(得分:1)

这有点主观,但我会说:

  1. 在发生故障时重新引发任何引发的异常(或使用Write-Error)
  2. 除非有意义或被要求,否则不要产生输出
  3. 解析输出并返回正确的对象,而不仅仅是从您执行的可执行文件中输出字符串
  4. 在您的示例中,我可能会添加[Switch]$PassThru参数并返回Archive.zip的FileInfo对象:Write-Output $(Get-Item $Archive)(如果存在)