【发布时间】:2021-05-20 22:09:48
【问题描述】:
我正在为我们的 JavaScript 项目构建构建环境。我们使用 require.js (r.js) 将不同的 js 模块组合成一个输出 js 文件。我们使用 TeamCity,我想配置调用 r.js 的 Powershell 构建步骤,读取它的标准输出和退出代码,然后将该退出代码传递回 TeamCity(通过使用此退出代码从 Powershell 退出),这样如果任务失败( r.js 返回退出代码 1) 它不会继续执行其他构建步骤。我还希望将 r.js 的标准输出保存在 TeamCity 日志中,以便开发人员快速查看导致 r.js 停止的错误。
这是我可以使用它的参数启动 r.js 进程、读取它的退出代码并使用它从 Powershell 退出的方式:
$process = start-process r.js.cmd -ArgumentList "-o build-dev.js" -PassThru -Wait
exit $process.ExitCode
如果我在退出前尝试以这种方式读取标准输出:
Write-Host $process.StandardOutput.ReadToEnd();
我收到此错误,这可能表明我无法以这种方式读取 StandardOutput,因为它是一个流:
您不能在空值表达式上调用方法。 在行:1 字符:45 + 写入主机 $process.StandardOutput.ReadToEnd
进程以代码 1 退出
现在我找到了一种运行进程的方法,这样我就可以读取标准输出但我无法读取退出代码:
$psi = New-object System.Diagnostics.ProcessStartInfo
$psi.UseShellExecute = $false
$psi.RedirectStandardOutput = $true
$psi.RedirectStandardError = $true
#$psi.FileName = "r.js.cmd"
$psi.FileName = "C:\Users\Administrator\AppData\Roaming\npm\r.js.cmd"
$psi.Arguments = @("-o build-dev.js")
#$psi.WorkingDirectory = (Get-Location).Path;
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $psi
$process.Start() | Out-Host
$process.WaitForExit()
$output = $process.StandardOutput.ReadToEnd()
$stderr = $process.StandardError.ReadToEnd()
sleep(10)
$exit_code = $process.ExitCode
write-host "========== OUTPUT =========="
write-host $output
write-host "========== ERROR =========="
write-host $stderr
write-host "========== EXIT CODE =========="
write-host $exit_code
write-host "========== $LastExitCode =========="
#write-host $LastExitCode
#Exit $exit_code
但这再次返回控制台输出,但退出代码始终为 0,即使 r.js 返回 1,因为我的 js 脚本中有错误。
谁能建议我如何使用 start-process 读取标准输出或如何使用 New-object System.Diadnostics.ProcessStartInfo 读取退出代码
如果有助于回答问题,我可以附上我的 TC 构建步骤配置和输出保存到构建日志的更多详细信息的屏幕截图。
【问题讨论】:
-
你不能用
$result = r.js.cmd -o build-dev.js; $exit_code = $LastExitCode吗? -
'r.js.cmd' 是 CMD 脚本吗?如果是这样,您确定它实际上会生成退出代码吗?如果 CMD 脚本正在启动执行构建的其他进程,它不仅需要报告退出代码,还需要将其冒泡,例如
exit %buildProcessExitCode% -
如果下面的链接是 r.is.cmd,那么它不会生成退出代码。需要进行修改才能这样做。或者用PS重写。 code.google.com/p/yarse/source/browse/node_modules/.bin/…
-
@KeithHill 如果我尝试这个:
$result = r.js.cmd -o build-dev.js; $exit_code = $LastExitCode它给了我这个:Result: Error: Line 14: Unexpected token { ...这很好,因为我故意在 js 文件中创建了一个错误以强制 r.js 失败并返回错误详细信息和退出代码 1。所以你可以看到我得到了标准输出。但它给了我退出代码 0 而不是 1。当我使用start-process时,我得到正确的退出代码。 -
@andyb 好建议,我会试一试。我注意到根据link 使用
start-process和-PassThru -Wait和-PassThru时正确读取退出代码为cmdlet 启动的每个进程返回一个进程对象。默认情况下,此 cmdlet 不会生成任何输出。 这可能是为什么 powershell 仍然能够从运行节点进程的 cmd 脚本中读取退出代码的原因,而节点进程本身并没有通过它。如果我删除-PassThru,我将无法正确读取退出代码。
标签: powershell requirejs teamcity build-process exit-code