如何"终止"获取内容 - 在另一个命令批量完成后等待?

时间:2018-01-29 08:05:57

标签: powershell batch-file jenkins parallel-processing batch-processing

我正在使用Jenkins编写Unity构建的批处理脚本。

到目前为止我做了什么

Unity有一个问题,默认情况下它在-batchmode中并不是非常冗长。

因此,为了将输出输入Jenkins,我使用-logFile使Unity写入特定的日志文件。

到目前为止,我只能在> 构建成功或使用

后读取此文件
Unity.exe -batchmode -logFile JenkinsLOG.txt <more parameters>

type JenkinsLOG.txt

现在,为了实时获取JenkinsLOG.txt的内容到Jenkins日志视图,我尝试使用start在新控制台中运行Unity进程并使用{{3将实时日志文件的内容打印到控制台:

start Unity.exe -batchmode -logFile JenkinsLOG.txt <more parameters>

powershell Get-Content JenkinsLOG.txt -Wait

这很有效,我看到实时输出出现在Jenkins ......

但是 ...当然,powershell命令永远不会终止,因此构建过程仍然会等待更多行附加到JenkinsLOG.txt

所以我的问题是 有没有可能告诉这个powershell命令在Unity进程完成后终止?

1 个答案:

答案 0 :(得分:1)

  • 获取您要监控的流程ID
  • 启动一个尾随日志文件的作业
  • 循环当前控制台以读取作业的输出
  • 进程退出时终止循环
  • 清理工作

这里包含在一个函数中。可能有一种更优雅的方式,但我找不到另一种方法来区分Wait-Process的“超时”退出和“流程停止”退出。

function TailFile-UntilProcessStops {
    Param ($processID, $filePath)

    $loopBlock = {
        Param($filePath) Get-Content $filePath -Wait -Tail 0
    }
    $TailLoopJob = start-job -scriptBlock $loopBlock -ArgumentList $filePath
    try {
        do {
            $TailLoopJob | Receive-Job
            try {
                Wait-Process -id $processID -ErrorAction Stop -Timeout 1
                $waitMore = $false
            } catch {
                $waitMore = $true
            }
        } while($waitMore)
    } finally {
        Stop-Job $TailLoopJob
        Remove-Job $TailLoopJob
    }
}

这是使用记事本的测试代码。确保文件存在,然后进行修改。每次保存时,控制台都应该使用更多数据进行更新。退出记事本和控件返回控制台。

$filename = 'h:\asdf\somefile.txt'
$process = start-process -FilePath 'notepad.exe' -ArgumentList @($filename) -PassThru
TailFile-UntilProcessStops -processID $process.id -filepath $filename